﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace Monitoring
{
    // For Benjamin.  From Nathan!

    // LONG STORY SHORT:
    // -------------------------------------------------------------------------------------------
    // CSDisk.DiskInfo[] disks = CSDisk.DiskUtil.EnumDisks();

    // That's what you plug in to whatever program you like ... and it spits out an enumeration of drives on your 'puter.

    // (This took a little more than a simple reg-ex macro, just to let you know! ... although, surprisingly, not *much* more ... )

    // This was actually a lot more work than I had planned on doing...
    // on the aside, I had wanted to see what would happen if I tried to port this
    // stuff over from VB.

    // It did go much quicker that I had the code in VB ... but regular expressions and search and replace can only go so far...
    // there was a lot about C# syntax that I had to just learn on the spot... and I didn't realize you had that limitation
    // of not being able to have multiple indexers in classes and structures.

    // Well ... the MemPtr I gave you is not as UTTERLY thorough as the one for VB, but this one works pretty fuckin' nice!
    // Have it, it's yours ... you'll see why the fuck I wrote it...

    // The rest of this was actually a bit of a nightmare for me, at first, but I became quite used to it.  I learned
    // all the fucking ins and outs, I followed the bouncing ball and I played with lots and lots of C++ example
    // code before I whittled it down into a logical method amongst the obvious madness.

    // But this was a good exercise, too ... I should always say I can program in C#... it's good for business, and the like...
    // also, it's generally really fun to challenge myself this way.

    // Okay.

    // There are a *LOT* of declares, here ... and a few functions of great utility that I threw in just because
    // I don't like doing anything half-assed.

    // You'll never worry about converting FILETIME to a DateTime ever again... lol ... Been there, done that ... ported it.

    // Amongst other things ... this is actually an extremely powerful and exhaustive little hardware API I've delivered ...

    // First we have to declare just a few things (just a smidge, a tiny little bit):

    #region Interop

    public enum MEDIA_TYPE
    {
        Unknown = 0x0,
        F5_1Pt2_512 = 0x1,
        F3_1Pt44_512 = 0x2,
        F3_2Pt88_512 = 0x3,
        F3_20Pt8_512 = 0x4,
        F3_720_512 = 0x5,
        F5_360_512 = 0x6,
        F5_320_512 = 0x7,
        F5_320_1024 = 0x8,
        F5_180_512 = 0x9,
        F5_160_512 = 0xA,
        RemovableMedia = 0xB,
        FixedMedia = 0xC,
        F3_120M_512 = 0xD,
        F3_640_512 = 0xE,
        F5_640_512 = 0xF,
        F5_720_512 = 0x10,
        F3_1Pt2_512 = 0x11,
        F3_1Pt23_1024 = 0x12,
        F5_1Pt23_1024 = 0x13,
        F3_128Mb_512 = 0x14,
        F3_230Mb_512 = 0x15,
        F8_256_128 = 0x16,
        F3_200Mb_512 = 0x17,
        F3_240M_512 = 0x18,
        F3_32M_512 = 0x19
    };

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode), TypeConverter(typeof(ExpandableObjectConverter))]
    public struct DISK_GEOMETRY {
        public long Cylinders;
        public MEDIA_TYPE MediaType;
        public uint TracksPerCylinder;
        public uint SectorsPerTrack;
        public uint BytesPerSector;

        public long TotalSectors
        {
            get
            {
                return (long)SectorsPerTrack * (long)TracksPerCylinder * (long)Cylinders;
            }
        }

        public override string ToString()
        {
            return SetupApi.PrintFriendlySize((ulong) TotalSectors * (ulong) BytesPerSector) + ", Total Sectors: " + TotalSectors.ToString("0,0") + ", Bytes Per Sector: " + BytesPerSector.ToString("0,0");
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode), TypeConverter(typeof(ExpandableObjectConverter))]
    public struct DISK_GEOMETRY_EX {
        public DISK_GEOMETRY Geometry;
        public ulong DiskSize;
        public byte Data;

        public override string ToString()
        {
            return Geometry.ToString();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct STORAGE_DEVICE_NUMBER {
        public uint DeviceType;
        public uint DeviceNumber;
        public uint PartitionNumber;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct FILETIME
    {
        private uint lo;
        private uint hi;

        public static implicit operator DateTime(FILETIME v)
        {
            SYSTEM_TIME st = new SYSTEM_TIME();
            FILETIME lft = new FILETIME();

            SYSTEM_TIME.FileTimeToLocalFileTime(ref v, ref lft);
            SYSTEM_TIME.FileTimeToSystemTime(ref lft, ref st);

            return new DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SYSTEM_TIME
    {
        [DllImport("kernel32.dll")]
        internal static extern int FileTimeToLocalFileTime(ref FILETIME ft, ref FILETIME lft);

        [DllImport("kernel32.dll")]
        internal static extern int FileTimeToSystemTime(ref FILETIME ft, ref SYSTEM_TIME st);

        public ushort wYear;
        public ushort wMonth;
        public ushort wDayOfWeek;
        public ushort wDay;
        public ushort wHour;
        public ushort wMinute;
        public ushort wSecond;
        public ushort wMilliseconds;
    };

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct CTL_CODE
    {
        public uint Value;

        public uint DeviceType
        {
            get
            {
                return (this.Value & 0xffff0000) >> 16;
            }
        }

        public uint Method
        {
            get
            {
                return (this.Value & 3);
            }
        }

        public CTL_CODE(uint DeviceType, uint Function, uint Method, uint Access)
        {
            this.Value = (DeviceType << 16) | (Access << 14) | (Function << 2) | Method;
        }

        public override String ToString()
        {
            return Value.ToString();
        }

        public static implicit operator uint(CTL_CODE c)
        {
            return c.Value;
        }

        public static implicit operator CTL_CODE(uint u)
        {
            CTL_CODE c = new CTL_CODE();
            c.Value = u;
            return c;
        }
    }

    [Flags]
    public enum FileAccess : uint
    {
        Read = (0x80000000),
        Write = (0x40000000),
        Execute = (0x20000000),
        All = (0x10000000),
                
        ReadData = (0x1),    // file & pipe
        ListDirectory = (0x1),    // directory

        WriteData = (0x2),    // file & pipe
        AddFile = (0x2),    // directory

        AppendData = (0x4),    // file
        AddSubDirectory = (0x4),    // directory
        CreatePipeInstance = (0x4),    // named pipe

        ReadEA = (0x8),    // file & directory

        WriteEA = (0x10),    // file & directory
        Traverse = (0x20),    // directory

        DeleteChild = (0x40),    // directory

        ReadAttributes = (0x80),    // all

        WriteAttributes = (0x100),    // all

        AllAccess = (IoCtl.STANDARD_RIGHTS_REQUIRED | IoCtl.SYNCHRONIZE | 0x1FF),

        GenericRead = (IoCtl.STANDARD_RIGHTS_READ |
                                           IoCtl.FILE_READ_DATA |
                                           IoCtl.FILE_READ_ATTRIBUTES |
                                           IoCtl.FILE_READ_EA |
                                           IoCtl.SYNCHRONIZE),

        GenericWrite = (IoCtl.STANDARD_RIGHTS_WRITE |
                                           IoCtl.FILE_WRITE_DATA |
                                           IoCtl.FILE_WRITE_ATTRIBUTES |
                                           IoCtl.FILE_WRITE_EA |
                                           IoCtl.FILE_APPEND_DATA |
                                           IoCtl.SYNCHRONIZE),

        GenericExecute = (IoCtl.STANDARD_RIGHTS_EXECUTE |
                                           IoCtl.FILE_READ_ATTRIBUTES |
                                           IoCtl.FILE_EXECUTE |
                                           IoCtl.SYNCHRONIZE),


    };

    [Flags]
    public enum ShareModes : uint
    {
        Read = 1,
        Write = 2,
        Delete = 4
    };

    public enum CreateDisposition : uint
    {
        CreateNew = 1,
        CreateAlways = 2,
        OpenExisting = 3,
        OpenAlways = 4,
        TruncateExisting = 5
    };

    [Flags]
    public enum FileFlags : uint
    {
        WriteThrough = 0x80000000,
        Overlapped = 0x40000000,
        NoBuffering = 0x20000000,
        RandomAccess = 0x10000000,
        SequentialScan = 0x8000000,
        DeleteOnClose = 0x4000000,
        BackupSemantics = 0x2000000,
        PosixSemantics = 0x1000000,
        SessionAware = 0x800000,
        OpenReparsePoint = 0x200000,
        OpenNoRecall = 0x100000,
        FirstPipeInstance = 0x80000,
        OpenRequiringOpLock = 0x40000
    }

    public static class FileIO
    {
        [DllImport("kernel32.dll", EntryPoint="CreateFileW", CharSet=CharSet.Unicode)]
        public static extern  IntPtr CreateFile(
                [MarshalAs(UnmanagedType.LPWStr)]
                String lpFileName,
                FileAccess dwDesiredAccess,
                ShareModes dwShareMode,
                IntPtr lpSecurityAttributes,
                CreateDisposition dwCreationDisposition,
                FileFlags dwFlagsAndAttributes,
                IntPtr hTemplateFile
                );

        [DllImport("kernel32.dll")]
        public static extern bool CloseHandle(IntPtr handle);
    }

    /// <summary>
    /// Enumeration flags for the SetupDiGetClassDevs
    /// </summary>
    /// <remarks></remarks>
    [Flags]
    public enum ClassDevFlags : int
    {
        /// <summary>
        /// return only the device that is associated with the system default device interface, if one is set, for the specified device interface classes.
        /// </summary>
        /// <remarks></remarks>
        Default = 1,

        /// <summary>
        /// return only devices that are currently present in a system.
        /// </summary>
        /// <remarks></remarks>
        Present = 2,

        /// <summary>
        /// return a list of installed devices for all device setup classes or all device interface classes.
        /// </summary>
        /// <remarks></remarks>
        AllClasses = 4,

        /// <summary>
        /// return only devices that are a part of the current hardware profile.
        /// </summary>
        /// <remarks></remarks>
        Profile = 8,

        /// <summary>
        /// return devices that support device interfaces for the specified device interface classes.
        /// This flag must be set in the Flags parameter if the Enumerator parameter specifies a device instance ID.
        /// </summary>
        /// <remarks></remarks>
        DeviceInterface = 0x10
    }

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct SP_DEVICE_INTERFACE_DATA
    {
        public uint cbSize;
        public Guid InterfaceClassGuid;
        public uint Flags;
        public long Reserved;
    };

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct SP_DEVICE_INTERFACE_DETAIL_DATA
    {
        public uint cbSize;

        // this is a byval array of unknown size.
        public char DevicePath;
    };

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct SP_DEVINFO_DATA
    {
        public uint cbSize;
        public Guid ClassGuid;
        public uint DevInst;
        public long Reserved;
    };

    public enum DEVPROP_BOOLEAN : byte
    {
        DEVPROP_FALSE = 0,
        DEVPROP_TRUE = 0xFF
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct DEVPROPKEY
    {
        [MarshalAs(UnmanagedType.Struct)]
        public Guid fmtid;

        public uint pid;

        public DEVPROPKEY(uint i1, ushort s1, ushort s2, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, uint pid)
        {
            fmtid = new Guid(i1, s1, s2, b1, b2, b3, b4, b5, b6, b7, b8);
            this.pid = pid;
        }
    }

    public static class SetupApi
    {
        public static string PrintFriendlySize(ulong size, string format = null) {
            double fs;
            string nom;

            if (size >= ((double) 1024 * 1024 * 1024 * 1024)) {
                fs = (size / ((double) 1024 * 1024 * 1024 * 1024));
                nom = "TiB";
            }
            else if (size >= ((double) 1024 * 1024 * 1024)) {
                fs = (size / ((double) 1024 * 1024 * 1024));
                nom = "GiB";
            }
            else if (size >= ((double) 1024 * 1024)) {
                fs = (size / ((double) 1024 * 1024));
                nom = "MiB";
            }
            else if (size >= ((double) 1024)) {
                fs = (size / ((double) 1024));
                nom = "KiB";
            }
            else {
                fs = size;
                nom = "B";
            }

            if (format != null) {
                return Math.Round(fs, 2).ToString(format) + " " + nom;
            }
            else {
                return Math.Round(fs, 2) + " " + nom;
            }
        }

        #region ClassDevs

        public static readonly Guid GUID_DEVCLASS_1394 = new Guid(0x6BDD1FC1, 0x810F, 0x11D0, 0xBE, 0xC7, 0x8, 0x0, 0x2B, 0xE2, 0x9, 0x2F);
        public static readonly Guid GUID_DEVCLASS_1394DEBUG = new Guid(0x66F250D6, 0x7801, 0x4A64, 0xB1, 0x39, 0xEE, 0xA8, 0xA, 0x45, 0xB, 0x24);
        public static readonly Guid GUID_DEVCLASS_61883 = new Guid(0x7EBEFBC0, 0x3200, 0x11D2, 0xB4, 0xC2, 0x0, 0xA0, 0xC9, 0x69, 0x7D, 0x7);
        public static readonly Guid GUID_DEVCLASS_ADAPTER = new Guid(0x4D36E964, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_APMSUPPORT = new Guid(0xD45B1C18, 0xC8FA, 0x11D1, 0x9F, 0x77, 0x0, 0x0, 0xF8, 0x5, 0xF5, 0x30);
        public static readonly Guid GUID_DEVCLASS_AVC = new Guid(0xC06FF265, 0xAE09, 0x48F0, 0x81, 0x2C, 0x16, 0x75, 0x3D, 0x7C, 0xBA, 0x83);
        public static readonly Guid GUID_DEVCLASS_BATTERY = new Guid(0x72631E54, 0x78A4, 0x11D0, 0xBC, 0xF7, 0x0, 0xAA, 0x0, 0xB7, 0xB3, 0x2A);
        public static readonly Guid GUID_DEVCLASS_BIOMETRIC = new Guid(0x53D29EF7, 0x377C, 0x4D14, 0x86, 0x4B, 0xEB, 0x3A, 0x85, 0x76, 0x93, 0x59);
        public static readonly Guid GUID_DEVCLASS_BLUETOOTH = new Guid(0xE0CBF06C, 0xCD8B, 0x4647, 0xBB, 0x8A, 0x26, 0x3B, 0x43, 0xF0, 0xF9, 0x74);
        public static readonly Guid GUID_DEVCLASS_CDROM = new Guid(0x4D36E965, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_COMPUTER = new Guid(0x4D36E966, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_DECODER = new Guid(0x6BDD1FC2, 0x810F, 0x11D0, 0xBE, 0xC7, 0x8, 0x0, 0x2B, 0xE2, 0x9, 0x2F);
        public static readonly Guid GUID_DEVCLASS_DISKDRIVE = new Guid(0x4D36E967, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_DISPLAY = new Guid(0x4D36E968, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_DOT4 = new Guid(0x48721B56, 0x6795, 0x11D2, 0xB1, 0xA8, 0x0, 0x80, 0xC7, 0x2E, 0x74, 0xA2);
        public static readonly Guid GUID_DEVCLASS_DOT4PRINT = new Guid(0x49CE6AC8, 0x6F86, 0x11D2, 0xB1, 0xE5, 0x0, 0x80, 0xC7, 0x2E, 0x74, 0xA2);
        public static readonly Guid GUID_DEVCLASS_ENUM1394 = new Guid(0xC459DF55, 0xDB08, 0x11D1, 0xB0, 0x9, 0x0, 0xA0, 0xC9, 0x8, 0x1F, 0xF6);
        public static readonly Guid GUID_DEVCLASS_FDC = new Guid(0x4D36E969, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_FLOPPYDISK = new Guid(0x4D36E980, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_GPS = new Guid(0x6BDD1FC3, 0x810F, 0x11D0, 0xBE, 0xC7, 0x8, 0x0, 0x2B, 0xE2, 0x9, 0x2F);
        public static readonly Guid GUID_DEVCLASS_HDC = new Guid(0x4D36E96A, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_HIDCLASS = new Guid(0x745A17A0, 0x74D3, 0x11D0, 0xB6, 0xFE, 0x0, 0xA0, 0xC9, 0xF, 0x57, 0xDA);
        public static readonly Guid GUID_DEVCLASS_IMAGE = new Guid(0x6BDD1FC6, 0x810F, 0x11D0, 0xBE, 0xC7, 0x8, 0x0, 0x2B, 0xE2, 0x9, 0x2F);
        public static readonly Guid GUID_DEVCLASS_INFINIBAND = new Guid(0x30EF7132, 0xD858, 0x4A0C, 0xAC, 0x24, 0xB9, 0x2, 0x8A, 0x5C, 0xCA, 0x3F);
        public static readonly Guid GUID_DEVCLASS_INFRARED = new Guid(0x6BDD1FC5, 0x810F, 0x11D0, 0xBE, 0xC7, 0x8, 0x0, 0x2B, 0xE2, 0x9, 0x2F);
        public static readonly Guid GUID_DEVCLASS_KEYBOARD = new Guid(0x4D36E96B, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_LEGACYDRIVER = new Guid(0x8ECC055D, 0x47F, 0x11D1, 0xA5, 0x37, 0x0, 0x0, 0xF8, 0x75, 0x3E, 0xD1);
        public static readonly Guid GUID_DEVCLASS_MEDIA = new Guid(0x4D36E96C, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_MEDIUM_CHANGER = new Guid(0xCE5939AE, 0xEBDE, 0x11D0, 0xB1, 0x81, 0x0, 0x0, 0xF8, 0x75, 0x3E, 0xC4);
        public static readonly Guid GUID_DEVCLASS_MEMORY = new Guid(0x5099944A, 0xF6B9, 0x4057, 0xA0, 0x56, 0x8C, 0x55, 0x2, 0x28, 0x54, 0x4C);
        public static readonly Guid GUID_DEVCLASS_MODEM = new Guid(0x4D36E96D, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_MONITOR = new Guid(0x4D36E96E, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_MOUSE = new Guid(0x4D36E96F, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_MTD = new Guid(0x4D36E970, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_MULTIFUNCTION = new Guid(0x4D36E971, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_MULTIPORTSERIAL = new Guid(0x50906CB8, 0xBA12, 0x11D1, 0xBF, 0x5D, 0x0, 0x0, 0xF8, 0x5, 0xF5, 0x30);
        public static readonly Guid GUID_DEVCLASS_NET = new Guid(0x4D36E972, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_NETCLIENT = new Guid(0x4D36E973, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_NETSERVICE = new Guid(0x4D36E974, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_NETTRANS = new Guid(0x4D36E975, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_NODRIVER = new Guid(0x4D36E976, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_PCMCIA = new Guid(0x4D36E977, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_PNPPRINTERS = new Guid(0x4658EE7E, 0xF050, 0x11D1, 0xB6, 0xBD, 0x0, 0xC0, 0x4F, 0xA3, 0x72, 0xA7);
        public static readonly Guid GUID_DEVCLASS_PORTS = new Guid(0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_PRINTER = new Guid(0x4D36E979, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_PRINTERUPGRADE = new Guid(0x4D36E97A, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_PROCESSOR = new Guid(0x50127DC3, 0xF36, 0x415E, 0xA6, 0xCC, 0x4C, 0xB3, 0xBE, 0x91, 0xB, 0x65);
        public static readonly Guid GUID_DEVCLASS_SBP2 = new Guid(0xD48179BE, 0xEC20, 0x11D1, 0xB6, 0xB8, 0x0, 0xC0, 0x4F, 0xA3, 0x72, 0xA7);
        public static readonly Guid GUID_DEVCLASS_SCSIADAPTER = new Guid(0x4D36E97B, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_SECURITYACCELERATOR = new Guid(0x268C95A1, 0xEDFE, 0x11D3, 0x95, 0xC3, 0x0, 0x10, 0xDC, 0x40, 0x50, 0xA5);
        public static readonly Guid GUID_DEVCLASS_SENSOR = new Guid(0x5175D334, 0xC371, 0x4806, 0xB3, 0xBA, 0x71, 0xFD, 0x53, 0xC9, 0x25, 0x8D);
        public static readonly Guid GUID_DEVCLASS_SIDESHOW = new Guid(0x997B5D8D, 0xC442, 0x4F2E, 0xBA, 0xF3, 0x9C, 0x8E, 0x67, 0x1E, 0x9E, 0x21);
        public static readonly Guid GUID_DEVCLASS_SMARTCARDREADER = new Guid(0x50DD5230, 0xBA8A, 0x11D1, 0xBF, 0x5D, 0x0, 0x0, 0xF8, 0x5, 0xF5, 0x30);
        public static readonly Guid GUID_DEVCLASS_SOUND = new Guid(0x4D36E97C, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_SYSTEM = new Guid(0x4D36E97D, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_TAPEDRIVE = new Guid(0x6D807884, 0x7D21, 0x11CF, 0x80, 0x1C, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_UNKNOWN = new Guid(0x4D36E97E, 0xE325, 0x11CE, 0xBF, 0xC1, 0x8, 0x0, 0x2B, 0xE1, 0x3, 0x18);
        public static readonly Guid GUID_DEVCLASS_USB = new Guid(0x36FC9E60, 0xC465, 0x11CF, 0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);
        public static readonly Guid GUID_DEVCLASS_VOLUME = new Guid(0x71A27CDD, 0x812A, 0x11D0, 0xBE, 0xC7, 0x8, 0x0, 0x2B, 0xE2, 0x9, 0x2F);
        public static readonly Guid GUID_DEVCLASS_VOLUMESNAPSHOT = new Guid(0x533C5B84, 0xEC70, 0x11D2, 0x95, 0x5, 0x0, 0xC0, 0x4F, 0x79, 0xDE, 0xAF);
        public static readonly Guid GUID_DEVCLASS_WCEUSBS = new Guid(0x25DBCE51, 0x6C8F, 0x4A72, 0x8A, 0x6D, 0xB5, 0x4C, 0x2B, 0x4F, 0xC8, 0x35);
        public static readonly Guid GUID_DEVCLASS_WPD = new Guid(0xEEC5AD98, 0x8080, 0x425F, 0x92, 0x2A, 0xDA, 0xBF, 0x3D, 0xE3, 0xF6, 0x9A);
        public static readonly Guid GUID_DEVCLASS_EHSTORAGESILO = new Guid(0x9DA2B80F, 0xF89F, 0x4A49, 0xA5, 0xC2, 0x51, 0x1B, 0x8, 0x5B, 0x9E, 0x8A);
        public static readonly Guid GUID_DEVCLASS_FIRMWARE = new Guid(0xF2E7DD72, 0x6468, 0x4E36, 0xB6, 0xF1, 0x64, 0x88, 0xF4, 0x2C, 0x1B, 0x52);
        public static readonly Guid GUID_DEVCLASS_EXTENSION = new Guid(0xE2F84CE7, 0x8EFA, 0x411C, 0xAA, 0x69, 0x97, 0x45, 0x4C, 0xA4, 0xCB, 0x57);

        //
        // Define filesystem filter classes used for classification and load ordering.
        // Classes are listed below in order from "highest" (i.e., farthest from the
        // filesystem) to "lowest" (i.e., closest to the filesystem).
        //
        public static readonly Guid GUID_DEVCLASS_FSFILTER_TOP = new Guid(0xB369BAF4, 0x5568, 0x4E82, 0xA8, 0x7E, 0xA9, 0x3E, 0xB1, 0x6B, 0xCA, 0x87);

        public static readonly Guid GUID_DEVCLASS_FSFILTER_ACTIVITYMONITOR = new Guid(0xB86DFF51, 0xA31E, 0x4BAC, 0xB3, 0xCF, 0xE8, 0xCF, 0xE7, 0x5C, 0x9F, 0xC2);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_UNDELETE = new Guid(0xFE8F1572, 0xC67A, 0x48C0, 0xBB, 0xAC, 0xB, 0x5C, 0x6D, 0x66, 0xCA, 0xFB);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_ANTIVIRUS = new Guid(0xB1D1A169, 0xC54F, 0x4379, 0x81, 0xDB, 0xBE, 0xE7, 0xD8, 0x8D, 0x74, 0x54);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_REPLICATION = new Guid(0x48D3EBC4, 0x4CF8, 0x48FF, 0xB8, 0x69, 0x9C, 0x68, 0xAD, 0x42, 0xEB, 0x9F);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_CONTINUOUSBACKUP = new Guid(0x71AA14F8, 0x6FAD, 0x4622, 0xAD, 0x77, 0x92, 0xBB, 0x9D, 0x7E, 0x69, 0x47);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_CONTENTSCREENER = new Guid(0x3E3F0674, 0xC83C, 0x4558, 0xBB, 0x26, 0x98, 0x20, 0xE1, 0xEB, 0xA5, 0xC5);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_QUOTAMANAGEMENT = new Guid(0x8503C911, 0xA6C7, 0x4919, 0x8F, 0x79, 0x50, 0x28, 0xF5, 0x86, 0x6B, 0xC);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_SYSTEMRECOVERY = new Guid(0x2DB15374, 0x706E, 0x4131, 0xA0, 0xC7, 0xD7, 0xC7, 0x8E, 0xB0, 0x28, 0x9A);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_CFSMETADATASERVER = new Guid(0xCDCF0939, 0xB75B, 0x4630, 0xBF, 0x76, 0x80, 0xF7, 0xBA, 0x65, 0x58, 0x84);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_HSM = new Guid(0xD546500A, 0x2AEB, 0x45F6, 0x94, 0x82, 0xF4, 0xB1, 0x79, 0x9C, 0x31, 0x77);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_COMPRESSION = new Guid(0xF3586BAF, 0xB5AA, 0x49B5, 0x8D, 0x6C, 0x5, 0x69, 0x28, 0x4C, 0x63, 0x9F);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_ENCRYPTION = new Guid(0xA0A701C0, 0xA511, 0x42FF, 0xAA, 0x6C, 0x6, 0xDC, 0x3, 0x95, 0x57, 0x6F);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_VIRTUALIZATION = new Guid(0xF75A86C0, 0x10D8, 0x4C3A, 0xB2, 0x33, 0xED, 0x60, 0xE4, 0xCD, 0xFA, 0xAC);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_PHYSICALQUOTAMANAGEMENT = new Guid(0x6A0A8E78, 0xBBA6, 0x4FC4, 0xA7, 0x9, 0x1E, 0x33, 0xCD, 0x9, 0xD6, 0x7E);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_OPENFILEBACKUP = new Guid(0xF8ECAFA6, 0x66D1, 0x41A5, 0x89, 0x9B, 0x66, 0x58, 0x5D, 0x72, 0x16, 0xB7);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_SECURITYENHANCER = new Guid(0xD02BC3DA, 0xC8E, 0x4945, 0x9B, 0xD5, 0xF1, 0x88, 0x3C, 0x22, 0x6C, 0x8C);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_COPYPROTECTION = new Guid(0x89786FF1, 0x9C12, 0x402F, 0x9C, 0x9E, 0x17, 0x75, 0x3C, 0x7F, 0x43, 0x75);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_BOTTOM = new Guid(0x37765EA0, 0x5958, 0x4FC9, 0xB0, 0x4B, 0x2F, 0xDF, 0xEF, 0x97, 0xE5, 0x9E);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_SYSTEM = new Guid(0x5D1B9AAA, 0x1E2, 0x46AF, 0x84, 0x9F, 0x27, 0x2B, 0x3F, 0x32, 0x4C, 0x46);
        public static readonly Guid GUID_DEVCLASS_FSFILTER_INFRASTRUCTURE = new Guid(0xE55FA6F9, 0x128C, 0x4D04, 0xAB, 0xAB, 0x63, 0xC, 0x74, 0xB1, 0x45, 0x3A);

        public static readonly Guid BUS1394_CLASS_GUID = new Guid("6BDD1FC1-810F-11d0-BEC7-08002BE2092F");
        public static readonly Guid GUID_61883_CLASS = new Guid("7EBEFBC0-3200-11d2-B4C2-00A0C9697D07");
        public static readonly Guid GUID_DEVICE_APPLICATIONLAUNCH_BUTTON = new Guid("629758EE-986E-4D9E-8E47-DE27F8AB054D");
        public static readonly Guid GUID_DEVICE_BATTERY = new Guid("72631E54-78A4-11D0-BCF7-00AA00B7B32A");
        public static readonly Guid GUID_DEVICE_LID = new Guid("4AFA3D52-74A7-11d0-be5e-00A0C9062857");
        public static readonly Guid GUID_DEVICE_MEMORY = new Guid("3FD0F03D-92E0-45FB-B75C-5ED8FFB01021");
        public static readonly Guid GUID_DEVICE_MESSAGE_INDICATOR = new Guid("CD48A365-FA94-4CE2-A232-A1B764E5D8B4");
        public static readonly Guid GUID_DEVICE_PROCESSOR = new Guid("97FADB10-4E33-40AE-359C-8BEF029DBDD0");
        public static readonly Guid GUID_DEVICE_SYS_BUTTON = new Guid("4AFA3D53-74A7-11d0-be5e-00A0C9062857");
        public static readonly Guid GUID_DEVICE_THERMAL_ZONE = new Guid("4AFA3D51-74A7-11d0-be5e-00A0C9062857");
        public static readonly Guid GUID_BTHPORT_DEVICE_INTERFACE = new Guid("0850302A-B344-4fda-9BE9-90576B8D46F0");
        public static readonly Guid GUID_DEVINTERFACE_BRIGHTNESS = new Guid("FDE5BBA4-B3F9-46FB-BDAA-0728CE3100B4");
        public static readonly Guid GUID_DEVINTERFACE_DISPLAY_ADAPTER = new Guid("5B45201D-F2F2-4F3B-85BB-30FF1F953599");
        public static readonly Guid GUID_DEVINTERFACE_I2C = new Guid("2564AA4F-DDDB-4495-B497-6AD4A84163D7");
        public static readonly Guid GUID_DEVINTERFACE_IMAGE = new Guid("6BDD1FC6-810F-11D0-BEC7-08002BE2092F");
        public static readonly Guid GUID_DEVINTERFACE_MONITOR = new Guid("E6F07B5F-EE97-4a90-B076-33F57BF4EAA7");
        public static readonly Guid GUID_DEVINTERFACE_OPM = new Guid("BF4672DE-6B4E-4BE4-A325-68A91EA49C09");
        public static readonly Guid GUID_DEVINTERFACE_VIDEO_OUTPUT_ARRIVAL = new Guid("1AD9E4F0-F88D-4360-BAB9-4C2D55E564CD");
        public static readonly Guid GUID_DISPLAY_DEVICE_ARRIVAL = new Guid("1CA05180-A699-450A-9A0C-DE4FBE3DDD89");
        public static readonly Guid GUID_DEVINTERFACE_HID = new Guid("4D1E55B2-F16F-11CF-88CB-001111000030");
        public static readonly Guid GUID_DEVINTERFACE_KEYBOARD = new Guid("884b96c3-56ef-11d1-bc8c-00a0c91405dd");
        public static readonly Guid GUID_DEVINTERFACE_MOUSE = new Guid("378DE44C-56EF-11D1-BC8C-00A0C91405DD");
        public static readonly Guid GUID_DEVINTERFACE_MODEM = new Guid("2C7089AA-2E0E-11D1-B114-00C04FC2AAE4");
        public static readonly Guid GUID_DEVINTERFACE_NET = new Guid("CAC88484-7515-4C03-82E6-71A87ABAC361");
        public static readonly Guid GUID_DEVINTERFACE_SENSOR = new Guid(0xBA1BB692, 0x9B7A, 0x4833, 0x9A, 0x1E, 0x52, 0x5E, 0xD1, 0x34, 0xE7, 0xE2);
        public static readonly Guid GUID_DEVINTERFACE_COMPORT = new Guid("86E0D1E0-8089-11D0-9CE4-08003E301F73");
        public static readonly Guid GUID_DEVINTERFACE_PARALLEL = new Guid("97F76EF0-F883-11D0-AF1F-0000F800845C");
        public static readonly Guid GUID_DEVINTERFACE_PARCLASS = new Guid("811FC6A5-F728-11D0-A537-0000F8753ED1");
        public static readonly Guid GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR = new Guid("4D36E978-E325-11CE-BFC1-08002BE10318");
        public static readonly Guid GUID_DEVINTERFACE_CDCHANGER = new Guid("53F56312-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid GUID_DEVINTERFACE_CDROM = new Guid("53F56308-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid GUID_DEVINTERFACE_DISK = new Guid("53F56307-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid GUID_DEVINTERFACE_FLOPPY = new Guid("53F56311-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid GUID_DEVINTERFACE_MEDIUMCHANGER = new Guid("53F56310-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid GUID_DEVINTERFACE_PARTITION = new Guid("53F5630A-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid GUID_DEVINTERFACE_STORAGEPORT = new Guid("2ACCFE60-C130-11D2-B082-00A0C91EFB8B");
        public static readonly Guid GUID_DEVINTERFACE_TAPE = new Guid("53F5630B-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid GUID_DEVINTERFACE_VOLUME = new Guid("53F5630D-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid GUID_DEVINTERFACE_WRITEONCEDISK = new Guid("53F5630C-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid GUID_IO_VOLUME_DEVICE_INTERFACE = new Guid("53F5630D-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid MOUNTDEV_MOUNTED_DEVICE_GUID = new Guid("53F5630D-B6BF-11D0-94F2-00A0C91EFB8B");
        public static readonly Guid GUID_AVC_CLASS = new Guid("095780C3-48A1-4570-BD95-46707F78C2DC");
        public static readonly Guid GUID_VIRTUAL_AVC_CLASS = new Guid("616EF4D0-23CE-446D-A568-C31EB01913D0");
        public static readonly Guid KSCATEGORY_ACOUSTIC_ECHO_CANCEL = new Guid("BF963D80-C559-11D0-8A2B-00A0C9255AC1");
        public static readonly Guid KSCATEGORY_AUDIO = new Guid("6994AD04-93EF-11D0-A3CC-00A0C9223196");
        public static readonly Guid KSCATEGORY_AUDIO_DEVICE = new Guid("FBF6F530-07B9-11D2-A71E-0000F8004788");
        public static readonly Guid KSCATEGORY_AUDIO_GFX = new Guid("9BAF9572-340C-11D3-ABDC-00A0C90AB16F");
        public static readonly Guid KSCATEGORY_AUDIO_SPLITTER = new Guid("9EA331FA-B91B-45F8-9285-BD2BC77AFCDE");
        public static readonly Guid KSCATEGORY_BDA_IP_SINK = new Guid("71985F4A-1CA1-11d3-9CC8-00C04F7971E0");
        public static readonly Guid KSCATEGORY_BDA_NETWORK_EPG = new Guid("71985F49-1CA1-11d3-9CC8-00C04F7971E0");
        public static readonly Guid KSCATEGORY_BDA_NETWORK_PROVIDER = new Guid("71985F4B-1CA1-11d3-9CC8-00C04F7971E0");
        public static readonly Guid KSCATEGORY_BDA_NETWORK_TUNER = new Guid("71985F48-1CA1-11d3-9CC8-00C04F7971E0");
        public static readonly Guid KSCATEGORY_BDA_RECEIVER_COMPONENT = new Guid("FD0A5AF4-B41D-11d2-9C95-00C04F7971E0");
        public static readonly Guid KSCATEGORY_BDA_TRANSPORT_INFORMATION = new Guid("A2E3074F-6C3D-11d3-B653-00C04F79498E");
        public static readonly Guid KSCATEGORY_BRIDGE = new Guid("085AFF00-62CE-11CF-A5D6-28DB04C10000");
        public static readonly Guid KSCATEGORY_CAPTURE = new Guid("65E8773D-8F56-11D0-A3B9-00A0C9223196");
        public static readonly Guid KSCATEGORY_CLOCK = new Guid("53172480-4791-11D0-A5D6-28DB04C10000");
        public static readonly Guid KSCATEGORY_COMMUNICATIONSTRANSFORM = new Guid("CF1DDA2C-9743-11D0-A3EE-00A0C9223196");
        public static readonly Guid KSCATEGORY_CROSSBAR = new Guid("A799A801-A46D-11D0-A18C-00A02401DCD4");
        public static readonly Guid KSCATEGORY_DATACOMPRESSOR = new Guid("1E84C900-7E70-11D0-A5D6-28DB04C10000");
        public static readonly Guid KSCATEGORY_DATADECOMPRESSOR = new Guid("2721AE20-7E70-11D0-A5D6-28DB04C10000");
        public static readonly Guid KSCATEGORY_DATATRANSFORM = new Guid("2EB07EA0-7E70-11D0-A5D6-28DB04C10000");
        public static readonly Guid KSCATEGORY_DRM_DESCRAMBLE = new Guid("FFBB6E3F-CCFE-4D84-90D9-421418B03A8E");
        public static readonly Guid KSCATEGORY_ENCODER = new Guid("19689BF6-C384-48fd-AD51-90E58C79F70B");
        public static readonly Guid KSCATEGORY_ESCALANTE_PLATFORM_DRIVER = new Guid("74F3AEA8-9768-11D1-8E07-00A0C95EC22E");
        public static readonly Guid KSCATEGORY_FILESYSTEM = new Guid("760FED5E-9357-11D0-A3CC-00A0C9223196");
        public static readonly Guid KSCATEGORY_INTERFACETRANSFORM = new Guid("CF1DDA2D-9743-11D0-A3EE-00A0C9223196");
        public static readonly Guid KSCATEGORY_MEDIUMTRANSFORM = new Guid("CF1DDA2E-9743-11D0-A3EE-00A0C9223196");
        public static readonly Guid KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR = new Guid("830A44F2-A32D-476B-BE97-42845673B35A");
        public static readonly Guid KSCATEGORY_MIXER = new Guid("AD809C00-7B88-11D0-A5D6-28DB04C10000");
        public static readonly Guid KSCATEGORY_MULTIPLEXER = new Guid("7A5DE1D3-01A1-452c-B481-4FA2B96271E8");
        public static readonly Guid KSCATEGORY_NETWORK = new Guid("67C9CC3C-69C4-11D2-8759-00A0C9223196");
        public static readonly Guid KSCATEGORY_PREFERRED_MIDIOUT_DEVICE = new Guid("D6C50674-72C1-11D2-9755-0000F8004788");
        public static readonly Guid KSCATEGORY_PREFERRED_WAVEIN_DEVICE = new Guid("D6C50671-72C1-11D2-9755-0000F8004788");
        public static readonly Guid KSCATEGORY_PREFERRED_WAVEOUT_DEVICE = new Guid("D6C5066E-72C1-11D2-9755-0000F8004788");
        public static readonly Guid KSCATEGORY_PROXY = new Guid("97EBAACA-95BD-11D0-A3EA-00A0C9223196");
        public static readonly Guid KSCATEGORY_QUALITY = new Guid("97EBAACB-95BD-11D0-A3EA-00A0C9223196");
        public static readonly Guid KSCATEGORY_REALTIME = new Guid("EB115FFC-10C8-4964-831D-6DCB02E6F23F");
        public static readonly Guid KSCATEGORY_RENDER = new Guid("65E8773E-8F56-11D0-A3B9-00A0C9223196");
        public static readonly Guid KSCATEGORY_SPLITTER = new Guid("0A4252A0-7E70-11D0-A5D6-28DB04C10000");
        public static readonly Guid KSCATEGORY_SYNTHESIZER = new Guid("DFF220F3-F70F-11D0-B917-00A0C9223196");
        public static readonly Guid KSCATEGORY_SYSAUDIO = new Guid("A7C7A5B1-5AF3-11D1-9CED-00A024BF0407");
        public static readonly Guid KSCATEGORY_TEXT = new Guid("6994AD06-93EF-11D0-A3CC-00A0C9223196");
        public static readonly Guid KSCATEGORY_TOPOLOGY = new Guid("DDA54A40-1E4C-11D1-A050-405705C10000");
        public static readonly Guid KSCATEGORY_TVAUDIO = new Guid("A799A802-A46D-11D0-A18C-00A02401DCD4");
        public static readonly Guid KSCATEGORY_TVTUNER = new Guid("A799A800-A46D-11D0-A18C-00A02401DCD4");
        public static readonly Guid KSCATEGORY_VBICODEC = new Guid("07DAD660-22F1-11D1-A9F4-00C04FBBDE8F");
        public static readonly Guid KSCATEGORY_VIDEO = new Guid("6994AD05-93EF-11D0-A3CC-00A0C9223196");
        public static readonly Guid KSCATEGORY_VIRTUAL = new Guid("3503EAC4-1F26-11D1-8AB0-00A0C9223196");
        public static readonly Guid KSCATEGORY_VPMUX = new Guid("A799A803-A46D-11D0-A18C-00A02401DCD4");
        public static readonly Guid KSCATEGORY_WDMAUD = new Guid("3E227E76-690D-11D2-8161-0000F8775BF1");
        public static readonly Guid KSMFT_CATEGORY_AUDIO_DECODER = new Guid("9ea73fb4-ef7a-4559-8d5d-719d8f0426c7");
        public static readonly Guid KSMFT_CATEGORY_AUDIO_EFFECT = new Guid("11064c48-3648-4ed0-932e-05ce8ac811b7");
        public static readonly Guid KSMFT_CATEGORY_AUDIO_ENCODER = new Guid("91c64bd0-f91e-4d8c-9276-db248279d975");
        public static readonly Guid KSMFT_CATEGORY_DEMULTIPLEXER = new Guid("a8700a7a-939b-44c5-99d7-76226b23b3f1");
        public static readonly Guid KSMFT_CATEGORY_MULTIPLEXER = new Guid("059c561e-05ae-4b61-b69d-55b61ee54a7b");
        public static readonly Guid KSMFT_CATEGORY_OTHER = new Guid("90175d57-b7ea-4901-aeb3-933a8747756f");
        public static readonly Guid KSMFT_CATEGORY_VIDEO_DECODER = new Guid("d6c02d4b-6833-45b4-971a-05a4b04bab91");
        public static readonly Guid KSMFT_CATEGORY_VIDEO_EFFECT = new Guid("12e17c21-532c-4a6e-8a1c-40825a736397");
        public static readonly Guid KSMFT_CATEGORY_VIDEO_ENCODER = new Guid("f79eac7d-e545-4387-bdee-d647d7bde42a");
        public static readonly Guid KSMFT_CATEGORY_VIDEO_PROCESSOR = new Guid("302ea3fc-aa5f-47f9-9f7a-c2188bb16302");
        public static readonly Guid GUID_DEVINTERFACE_USB_DEVICE = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED");
        public static readonly Guid GUID_DEVINTERFACE_USB_HOST_CONTROLLER = new Guid("3ABF6F2D-71C4-462A-8A92-1E6861E6AF27");
        public static readonly Guid GUID_DEVINTERFACE_USB_HUB = new Guid("F18A0E88-C30C-11D0-8815-00A0C906BED8");
        public static readonly Guid GUID_DEVINTERFACE_WPD = new Guid("6AC27878-A6FA-4155-BA85-F98F491D4F33");
        public static readonly Guid GUID_DEVINTERFACE_WPD_PRIVATE = new Guid("BA0C718F-4DED-49B7-BDD3-FABE28661211");
        public static readonly Guid GUID_DEVINTERFACE_SIDESHOW = new Guid("152E5811-FEB9-4B00-90F4-D32947AE1681");

        #endregion ClassDevs

        #region Bus Type Guids

        public static readonly Guid GUID_BUS_TYPE_INTERNAL = new Guid(0x1530EA73, 0x86B, 0x11D1, 0xA0, 0x9F, 0x0, 0xC0, 0x4F, 0xC3, 0x40, 0xB1);
        public static readonly Guid GUID_BUS_TYPE_PCMCIA = new Guid(0x9343630, 0xAF9F, 0x11D0, 0x92, 0xE9, 0x0, 0x0, 0xF8, 0x1E, 0x1B, 0x30);
        public static readonly Guid GUID_BUS_TYPE_PCI = new Guid(0xC8EBDFB0, 0xB510, 0x11D0, 0x80, 0xE5, 0x0, 0xA0, 0xC9, 0x25, 0x42, 0xE3);
        public static readonly Guid GUID_BUS_TYPE_ISAPNP = new Guid(0xE676F854, 0xD87D, 0x11D0, 0x92, 0xB2, 0x0, 0xA0, 0xC9, 0x5, 0x5F, 0xC5);
        public static readonly Guid GUID_BUS_TYPE_EISA = new Guid(0xDDC35509, 0xF3FC, 0x11D0, 0xA5, 0x37, 0x0, 0x0, 0xF8, 0x75, 0x3E, 0xD1);
        public static readonly Guid GUID_BUS_TYPE_MCA = new Guid(0x1C75997A, 0xDC33, 0x11D0, 0x92, 0xB2, 0x0, 0xA0, 0xC9, 0x5, 0x5F, 0xC5);
        public static readonly Guid GUID_BUS_TYPE_SERENUM = new Guid(0x77114A87, 0x8944, 0x11D1, 0xBD, 0x90, 0x0, 0xA0, 0xC9, 0x6, 0xBE, 0x2D);
        public static readonly Guid GUID_BUS_TYPE_USB = new Guid(0x9D7DEBBC, 0xC85D, 0x11D1, 0x9E, 0xB4, 0x0, 0x60, 0x8, 0xC3, 0xA1, 0x9A);

        public static readonly Guid GUID_BUS_TYPE_LPTENUM = new Guid(0xC4CA1000, 0x2DDC, 0x11D5, 0xA1, 0x7A, 0x0, 0xC0, 0x4F, 0x60, 0x52, 0x4D);
        public static readonly Guid GUID_BUS_TYPE_USBPRINT = new Guid(0x441EE000, 0x4342, 0x11D5, 0xA1, 0x84, 0x0, 0xC0, 0x4F, 0x60, 0x52, 0x4D);
        public static readonly Guid GUID_BUS_TYPE_DOT4PRT = new Guid(0x441EE001, 0x4342, 0x11D5, 0xA1, 0x84, 0x0, 0xC0, 0x4F, 0x60, 0x52, 0x4D);
        public static readonly Guid GUID_BUS_TYPE_1394 = new Guid(0xF74E73EB, 0x9AC5, 0x45EB, 0xBE, 0x4D, 0x77, 0x2C, 0xC7, 0x1D, 0xDF, 0xB3);
        public static readonly Guid GUID_BUS_TYPE_HID = new Guid(0xEEAF37D0, 0x1963, 0x47C4, 0xAA, 0x48, 0x72, 0x47, 0x6D, 0xB7, 0xCF, 0x49);
        public static readonly Guid GUID_BUS_TYPE_AVC = new Guid(0xC06FF265, 0xAE09, 0x48F0, 0x81, 0x2C, 0x16, 0x75, 0x3D, 0x7C, 0xBA, 0x83);
        public static readonly Guid GUID_BUS_TYPE_IRDA = new Guid(0x7AE17DC1, 0xC944, 0x44D6, 0x88, 0x1F, 0x4C, 0x2E, 0x61, 0x5, 0x3B, 0xC1);
        public static readonly Guid GUID_BUS_TYPE_SD = new Guid(0xE700CC04, 0x4036, 0x4E89, 0x95, 0x79, 0x89, 0xEB, 0xF4, 0x5F, 0x0, 0xCD);

        public static readonly Guid GUID_BUS_TYPE_ACPI = new Guid(0xD7B46895, 0x1A, 0x4942, 0x89, 0x1F, 0xA7, 0xD4, 0x66, 0x10, 0xA8, 0x43);
        public static readonly Guid GUID_BUS_TYPE_SW_DEVICE = new Guid(0x6D10322, 0x7DE0, 0x4CEF, 0x8E, 0x25, 0x19, 0x7D, 0xE, 0x74, 0x42, 0xE2);

        #endregion Bus Type Guids

        #region DevPropKey

        //
        // Property type modifiers.  Used to modify base DEVPROP_TYPE_ values, as
        // appropriate.  Not valid as standalone DEVPROPTYPE values.
        //
        public const uint DEVPROP_TYPEMOD_ARRAY = 0x1000; // array of fixed-sized data elements

        public const uint DEVPROP_TYPEMOD_LIST = 0x2000; // list of variable-sized data elements

        //
        // Property data types.
        //
        public const uint DEVPROP_TYPE_EMPTY = 0x0;  // nothing, no property data

        public const uint DEVPROP_TYPE_NULL = 0x1;  // null property data
        public const uint DEVPROP_TYPE_SBYTE = 0x2;  // 8-bit signed int (SBYTE)
        public const uint DEVPROP_TYPE_BYTE = 0x3;  // 8-bit unsigned int (BYTE)
        public const uint DEVPROP_TYPE_INT16 = 0x4;  // 16-bit signed int (SHORT)
        public const uint DEVPROP_TYPE_UINT16 = 0x5;  // 16-bit unsigned int (USHORT)
        public const uint DEVPROP_TYPE_INT32 = 0x6;  // 32-bit signed int (LONG)
        public const uint DEVPROP_TYPE_UINT32 = 0x7;  // 32-bit unsigned int (ULONG)
        public const uint DEVPROP_TYPE_INT64 = 0x8;  // 64-bit signed int (LONG64)
        public const uint DEVPROP_TYPE_UINT64 = 0x9;  // 64-bit unsigned int (ULONG64)
        public const uint DEVPROP_TYPE_FLOAT = 0xA;  // 32-bit floating-point (FLOAT)
        public const uint DEVPROP_TYPE_DOUBLE = 0xB;  // 64-bit floating-point (DOUBLE)
        public const uint DEVPROP_TYPE_DECIMAL = 0xC;  // 128-bit data (DECIMAL)
        public const uint DEVPROP_TYPE_GUID = 0xD;  // 128-bit unique identifier (GUID)
        public const uint DEVPROP_TYPE_CURRENCY = 0xE;  // 64 bit signed int currency value (CURRENCY)
        public const uint DEVPROP_TYPE_DATE = 0xF;  // date (DATE)
        public const uint DEVPROP_TYPE_FILETIME = 0x10;  // file time (FILETIME)
        public const uint DEVPROP_TYPE_BOOLEAN = 0x11;  // 8-bit boolean = (DEVPROP_BOOLEAN)
        public const uint DEVPROP_TYPE_STRING = 0x12;  // null-terminated string
        public const uint DEVPROP_TYPE_STRING_LIST = (DEVPROP_TYPE_STRING | DEVPROP_TYPEMOD_LIST); // multi-sz string list
        public const uint DEVPROP_TYPE_SECURITY_DESCRIPTOR = 0x13;  // self-relative binary SECURITY_DESCRIPTOR
        public const uint DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING = 0x14;  // security descriptor string (SDDL format)
        public const uint DEVPROP_TYPE_DEVPROPKEY = 0x15;  // device property key = (DEVPROPKEY)
        public const uint DEVPROP_TYPE_DEVPROPTYPE = 0x16;  // device property type = (DEVPROPTYPE)
        public const uint DEVPROP_TYPE_BINARY = (DEVPROP_TYPE_BYTE | DEVPROP_TYPEMOD_ARRAY);  // custom binary data
        public const uint DEVPROP_TYPE_ERROR = 0x17;  // 32-bit Win32 system error code
        public const uint DEVPROP_TYPE_NTSTATUS = 0x18;  // 32-bit NTSTATUS code
        public const uint DEVPROP_TYPE_STRING_INDIRECT = 0x19;  // string resource (@[path\]<dllname>,-<strId>)

        /// <summary>
        /// Device property types.
        /// </summary>
        /// <remarks></remarks>
        public enum DevPropTypes : uint
        {
            /// <summary>
            /// nothing, no property data
            /// </summary>
            Empty = DEVPROP_TYPE_EMPTY,

            /// <summary>
            /// null property data
            /// </summary>
            Null = DEVPROP_TYPE_NULL,

            /// <summary>
            /// 8-bit signed int (SBYTE)
            /// </summary>
            SByte = DEVPROP_TYPE_SBYTE,

            /// <summary>
            /// 8-bit unsigned int (BYTE)
            /// </summary>
            Byte = DEVPROP_TYPE_BYTE,

            /// <summary>
            /// 16-bit signed int (SHORT)
            /// </summary>
            Int16 = DEVPROP_TYPE_INT16,

            /// <summary>
            /// 16-bit unsigned int (USHORT)
            /// </summary>
            UInt16 = DEVPROP_TYPE_UINT16,

            /// <summary>
            /// 32-bit signed int (LONG)
            /// </summary>
            Int32 = DEVPROP_TYPE_INT32,

            /// <summary>
            /// 32-bit unsigned int (ULONG)
            /// </summary>
            UInt32 = DEVPROP_TYPE_UINT32,

            /// <summary>
            /// 64-bit signed int (LONG64)
            /// </summary>
            Int64 = DEVPROP_TYPE_INT64,

            /// <summary>
            /// 64-bit unsigned int (ULONG64)
            /// </summary>
            UInt64 = DEVPROP_TYPE_UINT64,

            /// <summary>
            /// 32-bit floating-point (FLOAT)
            /// </summary>
            Float = DEVPROP_TYPE_FLOAT,

            /// <summary>
            /// 64-bit floating-point (DOUBLE)
            /// </summary>
            Double = DEVPROP_TYPE_DOUBLE,

            /// <summary>
            /// 128-bit data (DECIMAL)
            /// </summary>
            Decimal = DEVPROP_TYPE_DECIMAL,

            /// <summary>
            /// 128-bit unique identifier (GUID)
            /// </summary>
            Guid = DEVPROP_TYPE_GUID,

            /// <summary>
            /// 64 bit signed int currency value (CURRENCY)
            /// </summary>
            Currency = DEVPROP_TYPE_CURRENCY,

            /// <summary>
            /// date (DATE)
            /// </summary>
            Date = DEVPROP_TYPE_DATE,

            /// <summary>
            /// file time (FILETIME)
            /// </summary>
            FileTime = DEVPROP_TYPE_FILETIME,

            /// <summary>
            /// 8-bit boolean = (DEVPROP_BOOLEAN)
            /// </summary>
            Boolean = DEVPROP_TYPE_BOOLEAN,

            /// <summary>
            /// null-terminated string
            /// </summary>
            String = DEVPROP_TYPE_STRING,

            /// <summary>
            /// multi-sz string list
            /// </summary>
            StringList = (DEVPROP_TYPE_STRING | DEVPROP_TYPEMOD_LIST),

            /// <summary>
            /// self-relative binary SECURITY_DESCRIPTOR
            /// </summary>
            SecurityDescriptor = DEVPROP_TYPE_SECURITY_DESCRIPTOR,

            /// <summary>
            /// security descriptor string (SDDL format)
            /// </summary>
            SecurityDescriptorString = DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING,

            /// <summary>
            /// device property key = (DEVPROPKEY)
            /// </summary>
            DevPropKey = DEVPROP_TYPE_DEVPROPKEY,

            /// <summary>
            /// device property type = (DEVPROPTYPE)
            /// </summary>
            DevPropType = DEVPROP_TYPE_DEVPROPTYPE,

            /// <summary>
            /// custom binary data
            /// </summary>
            Binary = (DEVPROP_TYPE_BYTE | DEVPROP_TYPEMOD_ARRAY),

            /// <summary>
            /// 32-bit Win32 system error code
            /// </summary>
            Error = DEVPROP_TYPE_ERROR,

            /// <summary>
            /// 32-bit NTSTATUS code
            /// </summary>
            NTStatus = DEVPROP_TYPE_NTSTATUS,

            /// <summary>
            /// string resource (@[path\]&lt;dllname&gt;,-&lt;strId&gt;)
            /// </summary>
            StringIndirect = DEVPROP_TYPE_STRING_INDIRECT,

            /// <summary>
            /// Array property key type modifier.
            /// </summary>
            /// <remarks></remarks>
            Array = DEVPROP_TYPEMOD_ARRAY,

            /// <summary>
            /// List property key type modifier.
            /// </summary>
            /// <remarks></remarks>
            List = DEVPROP_TYPEMOD_LIST
        };

        //
        // Max base DEVPROP_TYPE_ and DEVPROP_TYPEMOD_ values.
        //
        public const uint MAX_DEVPROP_TYPE = 0x19;  // max valid DEVPROP_TYPE_ value

        public const uint MAX_DEVPROP_TYPEMOD = 0x2000;  // max valid DEVPROP_TYPEMOD_ value

        //
        // Bitmasks for extracting DEVPROP_TYPE_ and DEVPROP_TYPEMOD_ values.
        //
        public const uint DEVPROP_MASK_TYPE = 0xFFF;  // range for base DEVPROP_TYPE_ values

        public const uint DEVPROP_MASK_TYPEMOD = 0xF000;  // mask for DEVPROP_TYPEMOD_ type modifiers

        //
        // Property type specific data types.
        //

        // 8-bit boolean type definition for DEVPROP_TYPE_BOOLEAN (True=-1, False=0)

        //
        // DEVPKEY_NAME
        // Common DEVPKEY used to retrieve the display name for an object.
        //
        public static readonly DEVPROPKEY DEVPKEY_NAME = new DEVPROPKEY(0xB725F130, 0x47EF, 0x101A, 0xA5, 0xF1, 0x2, 0x60, 0x8C, 0x9E, 0xEB, 0xAC, 10);    // DEVPROP_TYPE_STRING

        //
        // Device properties
        // These DEVPKEYs correspond to the SetupAPI SPDRP_XXX device properties.
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_DeviceDesc = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 2);     // DEVPROP_TYPE_STRING

        public static readonly DEVPROPKEY DEVPKEY_Device_HardwareIds = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 3);     // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_CompatibleIds = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 4);     // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_Service = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 6);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_Class = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 9);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_ClassGuid = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 10);    // DEVPROP_TYPE_GUID
        public static readonly DEVPROPKEY DEVPKEY_Device_Driver = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 11);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_ConfigFlags = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 12);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_Manufacturer = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 13);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_FriendlyName = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 14);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_LocationInfo = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 15);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_PDOName = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 16);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_Capabilities = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 17);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_UINumber = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 18);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_UpperFilters = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 19);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_LowerFilters = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 20);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_BusTypeGuid = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 21);    // DEVPROP_TYPE_GUID
        public static readonly DEVPROPKEY DEVPKEY_Device_LegacyBusType = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 22);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_BusNumber = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 23);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_EnumeratorName = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 24);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_Security = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 25);    // DEVPROP_TYPE_SECURITY_DESCRIPTOR
        public static readonly DEVPROPKEY DEVPKEY_Device_SecuritySDS = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 26);    // DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DevType = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 27);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_Exclusive = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 28);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_Device_Characteristics = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 29);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_Address = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 30);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_UINumberDescFormat = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 31);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_PowerData = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 32);    // DEVPROP_TYPE_BINARY
        public static readonly DEVPROPKEY DEVPKEY_Device_RemovalPolicy = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 33);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_RemovalPolicyDefault = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 34);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_RemovalPolicyOverride = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 35);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_InstallState = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 36);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_LocationPaths = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 37);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_BaseContainerId = new DEVPROPKEY(0xA45C254E, 0xDF1C, 0x4EFD, 0x80, 0x20, 0x67, 0xD1, 0x46, 0xA8, 0x50, 0xE0, 38);    // DEVPROP_TYPE_GUID

        //
        // Device and Device Interface property
        // Common DEVPKEY used to retrieve the device instance id associated with devices and device interfaces.
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_InstanceId = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 256);   // DEVPROP_TYPE_STRING

        //
        // Device properties
        // These DEVPKEYs correspond to a device's status and problem code.
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_DevNodeStatus = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 2);     // DEVPROP_TYPE_UINT32

        public static readonly DEVPROPKEY DEVPKEY_Device_ProblemCode = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 3);     // DEVPROP_TYPE_UINT32

        //
        // Device properties
        // These DEVPKEYs correspond to a device's relations.
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_EjectionRelations = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 4);     // DEVPROP_TYPE_STRING_LIST

        public static readonly DEVPROPKEY DEVPKEY_Device_RemovalRelations = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 5);     // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_PowerRelations = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 6);     // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_BusRelations = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 7);     // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_Parent = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 8);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_Children = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 9);     // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_Siblings = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 10);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_TransportRelations = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 11);    // DEVPROP_TYPE_STRING_LIST

        //
        // Device property
        // This DEVPKEY corresponds to a the status code that resulted in a device to be in a problem state.
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_ProblemStatus = new DEVPROPKEY(0x4340A6C5, 0x93FA, 0x4706, 0x97, 0x2C, 0x7B, 0x64, 0x80, 0x8, 0xA5, 0xA7, 12);     // DEVPROP_TYPE_NTSTATUS

        //
        // Device properties
        // These DEVPKEYs are set for the corresponding types of root-enumerated devices.
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_Reported = new DEVPROPKEY(0x80497100, 0x8C73, 0x48B9, 0xAA, 0xD9, 0xCE, 0x38, 0x7E, 0x19, 0xC5, 0x6E, 2);     // DEVPROP_TYPE_BOOLEAN

        public static readonly DEVPROPKEY DEVPKEY_Device_Legacy = new DEVPROPKEY(0x80497100, 0x8C73, 0x48B9, 0xAA, 0xD9, 0xCE, 0x38, 0x7E, 0x19, 0xC5, 0x6E, 3);     // DEVPROP_TYPE_BOOLEAN

        //
        // Device Container Id
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_ContainerId = new DEVPROPKEY(0x8C7ED206, 0x3F8A, 0x4827, 0xB3, 0xAB, 0xAE, 0x9E, 0x1F, 0xAE, 0xFC, 0x6C, 2);     // DEVPROP_TYPE_GUID

        public static readonly DEVPROPKEY DEVPKEY_Device_InLocalMachineContainer = new DEVPROPKEY(0x8C7ED206, 0x3F8A, 0x4827, 0xB3, 0xAB, 0xAE, 0x9E, 0x1F, 0xAE, 0xFC, 0x6C, 4);    // DEVPROP_TYPE_BOOLEAN

        //
        // Device property
        // This DEVPKEY correspond to a device's model.
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_Model = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 39);    // DEVPROP_TYPE_STRING

        //
        // Device Experience related Keys
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_ModelId = new DEVPROPKEY(0x80D81EA6, 0x7473, 0x4B0C, 0x82, 0x16, 0xEF, 0xC1, 0x1A, 0x2C, 0x4C, 0x8B, 2);     // DEVPROP_TYPE_GUID

        public static readonly DEVPROPKEY DEVPKEY_Device_FriendlyNameAttributes = new DEVPROPKEY(0x80D81EA6, 0x7473, 0x4B0C, 0x82, 0x16, 0xEF, 0xC1, 0x1A, 0x2C, 0x4C, 0x8B, 3);     // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_ManufacturerAttributes = new DEVPROPKEY(0x80D81EA6, 0x7473, 0x4B0C, 0x82, 0x16, 0xEF, 0xC1, 0x1A, 0x2C, 0x4C, 0x8B, 4);     // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_PresenceNotForDevice = new DEVPROPKEY(0x80D81EA6, 0x7473, 0x4B0C, 0x82, 0x16, 0xEF, 0xC1, 0x1A, 0x2C, 0x4C, 0x8B, 5);     // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_Device_SignalStrength = new DEVPROPKEY(0x80D81EA6, 0x7473, 0x4B0C, 0x82, 0x16, 0xEF, 0xC1, 0x1A, 0x2C, 0x4C, 0x8B, 6);     // DEVPROP_TYPE_INT32
        public static readonly DEVPROPKEY DEVPKEY_Device_IsAssociateableByUserAction = new DEVPROPKEY(0x80D81EA6, 0x7473, 0x4B0C, 0x82, 0x16, 0xEF, 0xC1, 0x1A, 0x2C, 0x4C, 0x8B, 7); // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_Device_ShowInUninstallUI = new DEVPROPKEY(0x80D81EA6, 0x7473, 0x4B0C, 0x82, 0x16, 0xEF, 0xC1, 0x1A, 0x2C, 0x4C, 0x8B, 8);     // DEVPROP_TYPE_BOOLEAN

        //
        // Other Device properties
        //
        public static readonly DEVPROPKEY DEVPKEY_Numa_Proximity_Domain = DEVPKEY_Device_Numa_Proximity_Domain;

        public static readonly DEVPROPKEY DEVPKEY_Device_Numa_Proximity_Domain = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 1);     // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_DHP_Rebalance_Policy = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 2);     // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_Numa_Node = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 3);     // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_BusReportedDeviceDesc = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 4);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_IsPresent = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 5);     // DEVPROP_TYPE_BOOL
        public static readonly DEVPROPKEY DEVPKEY_Device_HasProblem = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 6);     // DEVPROP_TYPE_BOOL
        public static readonly DEVPROPKEY DEVPKEY_Device_ConfigurationId = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 7);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_ReportedDeviceIdsHash = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 8);     // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_PhysicalDeviceLocation = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 9);     // DEVPROP_TYPE_BINARY
        public static readonly DEVPROPKEY DEVPKEY_Device_BiosDeviceName = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 10);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverProblemDesc = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 11);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DebuggerSafe = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 12);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_PostInstallInProgress = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 13);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_Device_Stack = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 14);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_ExtendedConfigurationIds = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 15);  // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_IsRebootRequired = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 16);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_Device_FirmwareDate = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 17);    // DEVPROP_TYPE_FILETIME
        public static readonly DEVPROPKEY DEVPKEY_Device_FirmwareVersion = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 18);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_FirmwareRevision = new DEVPROPKEY(0x540B947E, 0x8B40, 0x45BC, 0xA8, 0xA2, 0x6A, 0xB, 0x89, 0x4C, 0xBD, 0xA2, 19);    // DEVPROP_TYPE_STRING

        //
        // Device Session Id
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_SessionId = new DEVPROPKEY(0x83DA6326, 0x97A6, 0x4088, 0x94, 0x53, 0xA1, 0x92, 0x3F, 0x57, 0x3B, 0x29, 6);     // DEVPROP_TYPE_UINT32

        //
        // Device activity timestamp properties
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_InstallDate = new DEVPROPKEY(0x83DA6326, 0x97A6, 0x4088, 0x94, 0x53, 0xA1, 0x92, 0x3F, 0x57, 0x3B, 0x29, 100);   // DEVPROP_TYPE_FILETIME

        public static readonly DEVPROPKEY DEVPKEY_Device_FirstInstallDate = new DEVPROPKEY(0x83DA6326, 0x97A6, 0x4088, 0x94, 0x53, 0xA1, 0x92, 0x3F, 0x57, 0x3B, 0x29, 101);   // DEVPROP_TYPE_FILETIME
        public static readonly DEVPROPKEY DEVPKEY_Device_LastArrivalDate = new DEVPROPKEY(0x83DA6326, 0x97A6, 0x4088, 0x94, 0x53, 0xA1, 0x92, 0x3F, 0x57, 0x3B, 0x29, 102);   // DEVPROP_TYPE_FILETIME
        public static readonly DEVPROPKEY DEVPKEY_Device_LastRemovalDate = new DEVPROPKEY(0x83DA6326, 0x97A6, 0x4088, 0x94, 0x53, 0xA1, 0x92, 0x3F, 0x57, 0x3B, 0x29, 103);   // DEVPROP_TYPE_FILETIME

        //
        // Device driver properties
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverDate = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 2);      // DEVPROP_TYPE_FILETIME

        public static readonly DEVPROPKEY DEVPKEY_Device_DriverVersion = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 3);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverDesc = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 4);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverInfPath = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 5);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverInfSection = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 6);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverInfSectionExt = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 7);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_MatchingDeviceId = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 8);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverProvider = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 9);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverPropPageProvider = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 10);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverCoInstallers = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 11);     // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_Device_ResourcePickerTags = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 12);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_ResourcePickerExceptions = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 13);   // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverRank = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 14);     // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_Device_DriverLogoLevel = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 15);     // DEVPROP_TYPE_UINT32

        //
        // Device properties
        // These DEVPKEYs may be set by the driver package installed for a device.
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_NoConnectSound = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 17);     // DEVPROP_TYPE_BOOLEAN

        public static readonly DEVPROPKEY DEVPKEY_Device_GenericDriverInstalled = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 18);     // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_Device_AdditionalSoftwareRequested = new DEVPROPKEY(0xA8B865DD, 0x2E3D, 0x4094, 0xAD, 0x97, 0xE5, 0x93, 0xA7, 0xC, 0x75, 0xD6, 19); //DEVPROP_TYPE_BOOLEAN

        //
        // Device safe-removal properties
        //
        public static readonly DEVPROPKEY DEVPKEY_Device_SafeRemovalRequired = new DEVPROPKEY(0xAFD97640, 0x86A3, 0x4210, 0xB6, 0x7C, 0x28, 0x9C, 0x41, 0xAA, 0xBE, 0x55, 2);    // DEVPROP_TYPE_BOOLEAN

        public static readonly DEVPROPKEY DEVPKEY_Device_SafeRemovalRequiredOverride = new DEVPROPKEY(0xAFD97640, 0x86A3, 0x4210, 0xB6, 0x7C, 0x28, 0x9C, 0x41, 0xAA, 0xBE, 0x55, 3); // DEVPROP_TYPE_BOOLEAN

        //
        // Device properties
        // These DEVPKEYs may be set by the driver package installed for a device.
        //
        public static readonly DEVPROPKEY DEVPKEY_DrvPkg_Model = new DEVPROPKEY(0xCF73BB51, 0x3ABF, 0x44A2, 0x85, 0xE0, 0x9A, 0x3D, 0xC7, 0xA1, 0x21, 0x32, 2);     // DEVPROP_TYPE_STRING

        public static readonly DEVPROPKEY DEVPKEY_DrvPkg_VendorWebSite = new DEVPROPKEY(0xCF73BB51, 0x3ABF, 0x44A2, 0x85, 0xE0, 0x9A, 0x3D, 0xC7, 0xA1, 0x21, 0x32, 3);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DrvPkg_DetailedDescription = new DEVPROPKEY(0xCF73BB51, 0x3ABF, 0x44A2, 0x85, 0xE0, 0x9A, 0x3D, 0xC7, 0xA1, 0x21, 0x32, 4);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DrvPkg_DocumentationLink = new DEVPROPKEY(0xCF73BB51, 0x3ABF, 0x44A2, 0x85, 0xE0, 0x9A, 0x3D, 0xC7, 0xA1, 0x21, 0x32, 5);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DrvPkg_Icon = new DEVPROPKEY(0xCF73BB51, 0x3ABF, 0x44A2, 0x85, 0xE0, 0x9A, 0x3D, 0xC7, 0xA1, 0x21, 0x32, 6);     // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DrvPkg_BrandingIcon = new DEVPROPKEY(0xCF73BB51, 0x3ABF, 0x44A2, 0x85, 0xE0, 0x9A, 0x3D, 0xC7, 0xA1, 0x21, 0x32, 7);     // DEVPROP_TYPE_STRING_LIST

        //
        // Device setup class properties
        // These DEVPKEYs correspond to the SetupAPI SPCRP_XXX setup class properties.
        //
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_UpperFilters = new DEVPROPKEY(0x4321918B, 0xF69E, 0x470D, 0xA5, 0xDE, 0x4D, 0x88, 0xC7, 0x5A, 0xD2, 0x4B, 19);    // DEVPROP_TYPE_STRING_LIST

        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_LowerFilters = new DEVPROPKEY(0x4321918B, 0xF69E, 0x470D, 0xA5, 0xDE, 0x4D, 0x88, 0xC7, 0x5A, 0xD2, 0x4B, 20);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_Security = new DEVPROPKEY(0x4321918B, 0xF69E, 0x470D, 0xA5, 0xDE, 0x4D, 0x88, 0xC7, 0x5A, 0xD2, 0x4B, 25);    // DEVPROP_TYPE_SECURITY_DESCRIPTOR
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_SecuritySDS = new DEVPROPKEY(0x4321918B, 0xF69E, 0x470D, 0xA5, 0xDE, 0x4D, 0x88, 0xC7, 0x5A, 0xD2, 0x4B, 26);    // DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_DevType = new DEVPROPKEY(0x4321918B, 0xF69E, 0x470D, 0xA5, 0xDE, 0x4D, 0x88, 0xC7, 0x5A, 0xD2, 0x4B, 27);    // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_Exclusive = new DEVPROPKEY(0x4321918B, 0xF69E, 0x470D, 0xA5, 0xDE, 0x4D, 0x88, 0xC7, 0x5A, 0xD2, 0x4B, 28);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_Characteristics = new DEVPROPKEY(0x4321918B, 0xF69E, 0x470D, 0xA5, 0xDE, 0x4D, 0x88, 0xC7, 0x5A, 0xD2, 0x4B, 29);    // DEVPROP_TYPE_UINT32

        //
        // Device setup class properties
        //
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_Name = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 2);      // DEVPROP_TYPE_STRING

        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_ClassName = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 3);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_Icon = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 4);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_ClassInstaller = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 5);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_PropPageProvider = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 6);      // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_NoInstallClass = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 7);      // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_NoDisplayClass = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 8);      // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_SilentInstall = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 9);      // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_NoUseClass = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 10);     // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_DefaultService = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 11);     // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_IconPath = new DEVPROPKEY(0x259ABFFC, 0x50A7, 0x47CE, 0xAF, 0x8, 0x68, 0xC9, 0xA7, 0xD7, 0x33, 0x66, 12);     // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_DHPRebalanceOptOut = new DEVPROPKEY(0xD14D3EF3, 0x66CF, 0x4BA2, 0x9D, 0x38, 0xD, 0xDB, 0x37, 0xAB, 0x47, 0x1, 2);    // DEVPROP_TYPE_BOOLEAN

        //
        // Other Device setup class properties
        //
        public static readonly DEVPROPKEY DEVPKEY_DeviceClass_ClassCoInstallers = new DEVPROPKEY(0x713D1703, 0xA2E2, 0x49F5, 0x92, 0x14, 0x56, 0x47, 0x2E, 0xF3, 0xDA, 0x5C, 2);     // DEVPROP_TYPE_STRING_LIST

        //
        // Device interface properties
        //
        public static readonly DEVPROPKEY DEVPKEY_DeviceInterface_FriendlyName = new DEVPROPKEY(0x26E516E, 0xB814, 0x414B, 0x83, 0xCD, 0x85, 0x6D, 0x6F, 0xEF, 0x48, 0x22, 2);     // DEVPROP_TYPE_STRING

        public static readonly DEVPROPKEY DEVPKEY_DeviceInterface_Enabled = new DEVPROPKEY(0x26E516E, 0xB814, 0x414B, 0x83, 0xCD, 0x85, 0x6D, 0x6F, 0xEF, 0x48, 0x22, 3);     // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceInterface_ClassGuid = new DEVPROPKEY(0x26E516E, 0xB814, 0x414B, 0x83, 0xCD, 0x85, 0x6D, 0x6F, 0xEF, 0x48, 0x22, 4);     // DEVPROP_TYPE_GUID
        public static readonly DEVPROPKEY DEVPKEY_DeviceInterface_ReferenceString = new DEVPROPKEY(0x26E516E, 0xB814, 0x414B, 0x83, 0xCD, 0x85, 0x6D, 0x6F, 0xEF, 0x48, 0x22, 5);   // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceInterface_Restricted = new DEVPROPKEY(0x26E516E, 0xB814, 0x414B, 0x83, 0xCD, 0x85, 0x6D, 0x6F, 0xEF, 0x48, 0x22, 6);   // DEVPROP_TYPE_BOOLEAN

        //
        // Device interface class properties
        //
        public static readonly DEVPROPKEY DEVPKEY_DeviceInterfaceClass_DefaultInterface = new DEVPROPKEY(0x14C83A99, 0xB3F, 0x44B7, 0xBE, 0x4C, 0xA1, 0x78, 0xD3, 0x99, 0x5, 0x64, 2); // DEVPROP_TYPE_STRING

        public static readonly DEVPROPKEY DEVPKEY_DeviceInterfaceClass_Name = new DEVPROPKEY(0x14C83A99, 0xB3F, 0x44B7, 0xBE, 0x4C, 0xA1, 0x78, 0xD3, 0x99, 0x5, 0x64, 3); // DEVPROP_TYPE_STRING

        //
        // Device Container Properties
        //
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_Address = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 51);    // DEVPROP_TYPE_STRING  |  DEVPROP_TYPE_STRING_LIST

        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_DiscoveryMethod = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 52);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsEncrypted = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 53);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsAuthenticated = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 54);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsConnected = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 55);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsPaired = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 56);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_Icon = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 57);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_Version = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 65);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_Last_Seen = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 66);    // DEVPROP_TYPE_FILETIME
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_Last_Connected = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 67);    // DEVPROP_TYPE_FILETIME
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsShowInDisconnectedState = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 68);   // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsLocalMachine = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 70);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_MetadataPath = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 71);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsMetadataSearchInProgress = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 72);          // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_MetadataChecksum = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 73);            // DEVPROP_TYPE_BINARY
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsNotInterestingForDisplay = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 74);          // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_LaunchDeviceStageOnDeviceConnect = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 76);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_LaunchDeviceStageFromExplorer = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 77);       // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_BaselineExperienceId = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 78);    // DEVPROP_TYPE_GUID
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsDeviceUniquelyIdentifiable = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 79);        // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_AssociationArray = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 80);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_DeviceDescription1 = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 81);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_DeviceDescription2 = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 82);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_HasProblem = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 83);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsSharedDevice = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 84);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsNetworkDevice = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 85);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsDefaultDevice = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 86);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_MetadataCabinet = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 87);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_RequiresPairingElevation = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 88);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_ExperienceId = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 89);    // DEVPROP_TYPE_GUID
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_Category = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 90);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_Category_Desc_Singular = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 91);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_Category_Desc_Plural = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 92);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_Category_Icon = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 93);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_CategoryGroup_Desc = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 94);    // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_CategoryGroup_Icon = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 95);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_PrimaryCategory = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 97);    // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_UnpairUninstall = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 98);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_RequiresUninstallElevation = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 99);  // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_DeviceFunctionSubRank = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 100);   // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_AlwaysShowDeviceAsConnected = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 101);    // DEVPROP_TYPE_BOOLEAN
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_ConfigFlags = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 105);   // DEVPROP_TYPE_UINT32
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_PrivilegedPackageFamilyNames = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 106);   // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_CustomPrivilegedPackageFamilyNames = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 107);   // DEVPROP_TYPE_STRING_LIST
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_IsRebootRequired = new DEVPROPKEY(0x78C34FC8, 0x104A, 0x4ACA, 0x9E, 0xA4, 0x52, 0x4D, 0x52, 0x99, 0x6E, 0x57, 108);   // DEVPROP_TYPE_BOOLEAN

        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_FriendlyName = new DEVPROPKEY(0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 12288); // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_Manufacturer = new DEVPROPKEY(0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 8192);  // DEVPROP_TYPE_STRING
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_ModelName = new DEVPROPKEY(0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 8194);  // DEVPROP_TYPE_STRING (localizable);;
        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_ModelNumber = new DEVPROPKEY(0x656A3BB3, 0xECC0, 0x43FD, 0x84, 0x77, 0x4A, 0xE0, 0x40, 0x4A, 0x96, 0xCD, 8195);  // DEVPROP_TYPE_STRING

        public static readonly DEVPROPKEY DEVPKEY_DeviceContainer_InstallInProgress = new DEVPROPKEY(0x83DA6326, 0x97A6, 0x4088, 0x94, 0x53, 0xA1, 0x92, 0x3F, 0x57, 0x3B, 0x29, 9);     // DEVPROP_TYPE_BOOLEAN

        #endregion DevPropKey

        [DllImport("setupapi.dll", CharSet = CharSet.Unicode, EntryPoint = "SetupDiGetClassDevsW")]
        public static extern IntPtr SetupDiGetClassDevs(
            Guid ClassGuid,
            IntPtr Enumerator,
            IntPtr hwndParent,
            ClassDevFlags Flags
        );

        [DllImport("setupapi.dll", CharSet = CharSet.Unicode, EntryPoint = "SetupDiGetClassProperty")]
        public static extern bool SetupDiGetClassProperty(
            Guid ClassGuid,
            DEVPROPKEY PropertyKey,
            ref int propertyType,
            MemPtr propertyBuffer,
            int propertyBufferSize,
            ref int RequiredSize,
            int Flags
        );

        [DllImport("setupapi.dll")]
        public static extern bool SetupDiLoadClassIcon(
            Guid ClassGuid,
            ref IntPtr hIcon,
            ref int MiniIconIndex
        );

        [DllImport("setupapi.dll")]
        public static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);

        [DllImport("setupapi.dll")]
        public static extern int SetupDiEnumDeviceInterfaces(
            IntPtr DeviceInfoSet,
            ref SP_DEVINFO_DATA DeviceInfoData,
            ref Guid InterfaceClassGuid,
            uint MemberIndex,
            ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
        );

        [DllImport("setupapi.dll")]
        public static extern int SetupDiEnumDeviceInterfaces(
            IntPtr DeviceInfoSet,
            IntPtr DeviceInfoData,
            ref Guid InterfaceClassGuid,
            uint MemberIndex,
            ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
        );

        [DllImport("setupapi.dll")]
        public static extern int SetupDiEnumDeviceInterfaces(
            IntPtr DeviceInfoSet,
            IntPtr DeviceInfoData,
            ref Guid InterfaceClassGuid,
            uint MemberIndex,
            IntPtr DeviceInterfaceData
        );

        [DllImport("setupapi.dll")]
        public static extern bool SetupDiEnumDeviceInfo(
            IntPtr DeviceInfoSet,
            uint MemberIndex,
            ref SP_DEVINFO_DATA DeviceInfoData
        );

        [DllImport("setupapi.dll", CharSet = CharSet.Unicode, EntryPoint = "SetupDiGetDevicePropertyW")]
        public static extern bool SetupDiGetDeviceProperty(
            IntPtr DeviceInfoSet,
            ref SP_DEVINFO_DATA DeviceInfoData,
            DEVPROPKEY PropertyKey,
            ref DevPropTypes PropertyType,
            MemPtr PropertyBuffer,
            uint PropertyBufferSize,
            ref uint RequiredSize,
            uint Flags
        );

        [DllImport("setupapi.dll", CharSet = CharSet.Unicode, EntryPoint = "SetupDiGetDeviceInterfaceDetailW")]
        public static extern bool SetupDiGetDeviceInterfaceDetail(
            IntPtr DeviceInfoSet,
            ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
            ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
            uint DeviceInterfaceDetailDataSize,
            ref uint RequiredSize,
            ref SP_DEVINFO_DATA DeviceInfoData
        );

        [DllImport("setupapi.dll", CharSet = CharSet.Unicode, EntryPoint = "SetupDiGetDeviceInterfaceDetailW")]
        public static extern bool SetupDiGetDeviceInterfaceDetail(
            IntPtr DeviceInfoSet,
            ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
            MemPtr DeviceInterfaceDetailData,
            uint DeviceInterfaceDetailDataSize,
            ref uint RequiredSize,
            ref SP_DEVINFO_DATA DeviceInfoData
        );

        [DllImport("setupapi.dll", CharSet = CharSet.Unicode, EntryPoint = "SetupDiGetDeviceInterfaceDetailW")]
        public static extern bool SetupDiGetDeviceInterfaceDetail(
            IntPtr DeviceInfoSet,
            ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
            MemPtr DeviceInterfaceDetailData,
            uint DeviceInterfaceDetailDataSize,
            ref uint RequiredSize,
            IntPtr DeviceInfoData
        );

        [DllImport("setupapi.dll", CharSet = CharSet.Unicode, EntryPoint = "SetupDiGetDeviceInterfaceDetailW")]
        public static extern bool SetupDiGetDeviceInterfaceDetail(
            IntPtr DeviceInfoSet,
            IntPtr DeviceInterfaceData,
            ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
            uint DeviceInterfaceDetailDataSize,
            ref uint RequiredSize,
            IntPtr DeviceInfoData
        );

        [DllImport("setupapi.dll", CharSet = CharSet.Unicode, EntryPoint = "SetupDiGetDeviceInterfaceDetailW")]
        public static extern bool SetupDiGetDeviceInterfaceDetail(
            IntPtr DeviceInfoSet,
            IntPtr DeviceInterfaceData,
            MemPtr DeviceInterfaceDetailData,
            uint DeviceInterfaceDetailDataSize,
            ref uint RequiredSize,
            IntPtr DeviceInfoData
        );

        [DllImport("setupapi.dll", CharSet = CharSet.Unicode, EntryPoint = "SetupDiGetDeviceInterfaceDetailW")]
        public static extern bool SetupDiGetDeviceInterfaceDetail(
            IntPtr DeviceInfoSet,
            ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
            ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
            uint DeviceInterfaceDetailDataSize,
            ref uint RequiredSize,
            IntPtr DeviceInfoData
        );

        /// <summary>
        /// Digests a device property type and raw data and returns the equivalent CLR object.
        /// </summary>
        /// <param name="type">The property type.</param>
        /// <param name="data">The raw data pointer.</param>
        /// <param name="length">The length of the data.</param>
        /// <returns>A managed-memory object equivalent.</returns>
        /// <remarks></remarks>
        internal static Object internalDevPropToObject(DevPropTypes type, IntPtr data, int length = 0)
        {
            MemPtr mm = new MemPtr(data);
            object res = null;

            switch (type)
            {
                case DevPropTypes.Binary:
                    res = mm.GrabBytes(0, length);
                    break;

                case DevPropTypes.Boolean:
                    res = (object)(bool)(mm.byteAt(0) != 0);
                    break;

                case DevPropTypes.Byte:
                    res = mm.byteAt(0);
                    break;

                case DevPropTypes.SByte:
                    res = mm.sbyteAt(0);
                    break;

                case DevPropTypes.Int16:
                    res = mm.shortAt(0);
                    break;

                case DevPropTypes.UInt16:
                    res = mm.ushortAt(0);
                    break;

                case DevPropTypes.Int32:
                    res = mm.intAt(0);
                    break;

                case DevPropTypes.UInt32:
                    res = mm.uintAt(0);
                    break;

                case DevPropTypes.Int64:
                    res = mm.longAt(0);
                    break;

                case DevPropTypes.UInt64:
                    res = mm.ulongAt(0);
                    break;

                case DevPropTypes.Currency:

                    // I had to read the documentation on MSDN very carefully to understand why this needs to be.
                    res = (mm.doubleAt(0) * 10000.0);
                    break;

                case DevPropTypes.Float:
                    res = mm.floatAt(0);
                    break;

                case DevPropTypes.Double:
                    res = mm.doubleAt(0);
                    break;

                case DevPropTypes.Date:

                    // based on what the MSDN describes of this property format, this is what
                    // I believe needs to be done to make the value into an acceptable CLR DateTime object.
                    double d = mm.doubleAt(0);

                    TimeSpan t = new TimeSpan((int)(d * 24), 0, 0);
                    DateTime dt = new DateTime(1899, 12, 31);

                    dt.Add(t);
                    res = dt;
                    break;

                case DevPropTypes.Decimal:
                    res = mm.decimalAt(0);
                    break;

                case DevPropTypes.FileTime:

                    FILETIME ft = mm.ToStruct<FILETIME>();
                    res = (DateTime) ft;
                    break;

                case DevPropTypes.DevPropKey:
                    DEVPROPKEY dk;
                    dk = mm.ToStruct<DEVPROPKEY>();
                    res = dk;
                    break;

                case DevPropTypes.Guid:
                    res = mm.GuidAt(0);
                    break;

                case DevPropTypes.SecurityDescriptor:
                    res = (IntPtr) mm;
                    break;

                case DevPropTypes.String:
                    res = mm.ToString();
                    break;

                case DevPropTypes.StringList:
                    res = mm.GrabStringArray(0);
                    break;

                case DevPropTypes.DevPropType:
                    res = mm.intAt(0);
                    break;

                case DevPropTypes.SecurityDescriptorString:
                    res = mm.ToString();
                    break;

                case DevPropTypes.StringIndirect:
                    res = mm.ToString();
                    break;

                case DevPropTypes.NTStatus:
                    res = mm.intAt(0);
                    break;
            }

            return res;
        }

        /// <summary>
        /// Get an arbitrary device property from a previously-enumerated device.
        /// </summary>
        /// <param name="hDev">The open handle to the device.</param>
        /// <param name="devInfo">The device info structure.</param>
        /// <param name="prop">The DevPropKey value to retrieve.</param>
        /// <param name="type">The property type of the value to retrieve.</param>
        /// <param name="flags">Optional flags to pass.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public static object GetDevProperty(IntPtr hDev, SP_DEVINFO_DATA devInfo, DEVPROPKEY prop, DevPropTypes type, ClassDevFlags flags = ClassDevFlags.Present | ClassDevFlags.DeviceInterface)
        {
            uint c = 0;
            MemPtr mm;
            object o;

            SetupDiGetDeviceProperty(hDev,
                                     ref devInfo,
                                     prop,
                                     ref type,
                                     IntPtr.Zero,
                                     0,
                                     ref c,
                                     0);

            if (c == 0) return null;
            mm = new MemPtr(c);

            SetupDiGetDeviceProperty(hDev,
                                     ref devInfo,
                                     prop,
                                     ref type,
                                     mm,
                                     c,
                                     ref c,
                                     0);

            o = internalDevPropToObject(type, mm, (int)c);
            mm.Free();
            return o;
        }
    }

    public static class IoCtl
    {
        [DllImport("kernel32.dll")]
        public static extern  bool DeviceIoControl(
            IntPtr hDevice,
            uint DwIoControlCode,
            IntPtr lpInBuffer,
            uint nInBufferSize,
            IntPtr lpOutBuffer,
            uint nOutBufferSize,
            ref uint lpbytesreturned,
            IntPtr lpOverlapped);

        [DllImport("kernel32.dll")]
        public static extern  bool DeviceIoControl(
            IntPtr hDevice,
            uint DwIoControlCode,
            IntPtr lpInBuffer,
            uint nInBufferSize,
            STORAGE_DEVICE_NUMBER lpOutBuffer,
            uint nOutBufferSize,
            ref uint lpbytesreturned,
            IntPtr lpOverlapped);

        public const uint IOCTL_DISK_BASE = 7;

        public const uint METHOD_BUFFERED = 0;
        public const uint METHOD_IN_DIRECT = 1;
        public const uint METHOD_OUT_DIRECT = 2;
        public const uint METHOD_NEITHER = 3;

        public const uint IOCTL_STORAGE_BASE = 0x2d;

        public const uint FILE_ANY_ACCESS = 0;
        public const uint FILE_SPECIAL_ACCESS = (FILE_ANY_ACCESS);
        public const uint FILE_READ_ACCESS = (1);    // file & pipe
        public const uint FILE_WRITE_ACCESS = (2);    // file & pipe

        public static readonly CTL_CODE IOCTL_STORAGE_CHECK_VERIFY = new CTL_CODE(IOCTL_STORAGE_BASE, 0x200, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_CHECK_VERIFY2 = new CTL_CODE(IOCTL_STORAGE_BASE, 0x200, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_MEDIA_REMOVAL = new CTL_CODE(IOCTL_STORAGE_BASE, 0x201, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_EJECT_MEDIA = new CTL_CODE(IOCTL_STORAGE_BASE, 0x202, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_LOAD_MEDIA = new CTL_CODE(IOCTL_STORAGE_BASE, 0x203, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_LOAD_MEDIA2 = new CTL_CODE(IOCTL_STORAGE_BASE, 0x203, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_RESERVE = new CTL_CODE(IOCTL_STORAGE_BASE, 0x204, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_RELEASE = new CTL_CODE(IOCTL_STORAGE_BASE, 0x205, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_FIND_NEW_DEVICES = new CTL_CODE(IOCTL_STORAGE_BASE, 0x206, METHOD_BUFFERED, FILE_READ_ACCESS);

        public static readonly CTL_CODE IOCTL_STORAGE_EJECTION_CONTROL = new CTL_CODE(IOCTL_STORAGE_BASE, 0x250, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_MCN_CONTROL = new CTL_CODE(IOCTL_STORAGE_BASE, 0x251, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE IOCTL_STORAGE_GET_MEDIA_TYPES = new CTL_CODE(IOCTL_STORAGE_BASE, 0x300, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_GET_MEDIA_TYPES_EX = new CTL_CODE(IOCTL_STORAGE_BASE, 0x301, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER = new CTL_CODE(IOCTL_STORAGE_BASE, 0x304, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_GET_HOTPLUG_INFO = new CTL_CODE(IOCTL_STORAGE_BASE, 0x305, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_SET_HOTPLUG_INFO = new CTL_CODE(IOCTL_STORAGE_BASE, 0x306, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        public static readonly CTL_CODE IOCTL_STORAGE_RESET_BUS = new CTL_CODE(IOCTL_STORAGE_BASE, 0x400, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_RESET_DEVICE = new CTL_CODE(IOCTL_STORAGE_BASE, 0x401, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_BREAK_RESERVATION = new CTL_CODE(IOCTL_STORAGE_BASE, 0x405, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_PERSISTENT_RESERVE_IN = new CTL_CODE(IOCTL_STORAGE_BASE, 0x406, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_PERSISTENT_RESERVE_OUT = new CTL_CODE(IOCTL_STORAGE_BASE, 0x407, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        public static readonly CTL_CODE IOCTL_STORAGE_GET_DEVICE_NUMBER = new CTL_CODE(IOCTL_STORAGE_BASE, 0x420, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_PREDICT_FAILURE = new CTL_CODE(IOCTL_STORAGE_BASE, 0x440, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_FAILURE_PREDICTION_CONFIG = new CTL_CODE(IOCTL_STORAGE_BASE, 0x441, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_READ_CAPACITY = new CTL_CODE(IOCTL_STORAGE_BASE, 0x450, METHOD_BUFFERED, FILE_READ_ACCESS);

        //;
        // IOCTLs 0x0463 to 0x0468 reserved for dependent disk support.;
        //;

        //;
        // IOCTLs 0x0470 to 0x047f reserved for device and stack telemetry interfaces;
        //;

        public static readonly CTL_CODE IOCTL_STORAGE_GET_DEVICE_TELEMETRY = new CTL_CODE(IOCTL_STORAGE_BASE, 0x470, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_DEVICE_TELEMETRY_NOTIFY = new CTL_CODE(IOCTL_STORAGE_BASE, 0x471, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_DEVICE_TELEMETRY_QUERY_CAPS = new CTL_CODE(IOCTL_STORAGE_BASE, 0x472, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_GET_DEVICE_TELEMETRY_RAW = new CTL_CODE(IOCTL_STORAGE_BASE, 0x473, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        public static readonly CTL_CODE IOCTL_STORAGE_QUERY_PROPERTY = new CTL_CODE(IOCTL_STORAGE_BASE, 0x500, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES = new CTL_CODE(IOCTL_STORAGE_BASE, 0x501, METHOD_BUFFERED, FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_GET_LB_PROVISIONING_MAP_RESOURCES = new CTL_CODE(IOCTL_STORAGE_BASE, 0x502, METHOD_BUFFERED, FILE_READ_ACCESS);

        //;
        // IOCTLs 0x0503 to 0x0580 reserved for Enhanced Storage devices.;
        //;

        //;
        // IOCTLs for bandwidth contracts on storage devices;
        // (Move this to ntddsfio if we decide to use a new base);
        //;

        public static readonly CTL_CODE IOCTL_STORAGE_GET_BC_PROPERTIES = new CTL_CODE(IOCTL_STORAGE_BASE, 0x600, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_ALLOCATE_BC_STREAM = new CTL_CODE(IOCTL_STORAGE_BASE, 0x601, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_FREE_BC_STREAM = new CTL_CODE(IOCTL_STORAGE_BASE, 0x602, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        //;
        // IOCTL to check for priority support;
        //;
        public static readonly CTL_CODE IOCTL_STORAGE_CHECK_PRIORITY_HINT_SUPPORT = new CTL_CODE(IOCTL_STORAGE_BASE, 0x620, METHOD_BUFFERED, FILE_ANY_ACCESS);

        //;
        // IOCTL for data integrity check support;
        //;

        public static readonly CTL_CODE IOCTL_STORAGE_START_DATA_INTEGRITY_CHECK = new CTL_CODE(IOCTL_STORAGE_BASE, 0x621, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_STORAGE_STOP_DATA_INTEGRITY_CHECK = new CTL_CODE(IOCTL_STORAGE_BASE, 0x622, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        // begin_winioctl;

        //;
        // IOCTLs 0x0643 to 0x0655 reserved for VHD disk support.;
        //;

        //;
        // IOCTL to support Idle Power Management, including Device Wake;
        //;
        public static readonly CTL_CODE IOCTL_STORAGE_ENABLE_IDLE_POWER = new CTL_CODE(IOCTL_STORAGE_BASE, 0x720, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE IOCTL_STORAGE_GET_IDLE_POWERUP_REASON = new CTL_CODE(IOCTL_STORAGE_BASE, 0x721, METHOD_BUFFERED, FILE_ANY_ACCESS);

        //;
        // IOCTLs to allow class drivers to acquire and release active references on;
        // a unit.  These should only be used if the class driver previously sent a;
        // successful IOCTL_STORAGE_ENABLE_IDLE_POWER request to the port driver.;
        //;
        public static readonly CTL_CODE IOCTL_STORAGE_POWER_ACTIVE = new CTL_CODE(IOCTL_STORAGE_BASE, 0x722, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE IOCTL_STORAGE_POWER_IDLE = new CTL_CODE(IOCTL_STORAGE_BASE, 0x723, METHOD_BUFFERED, FILE_ANY_ACCESS);

        //;
        // This IOCTL indicates that the physical device has triggered some sort of event.;
        //;
        public static readonly CTL_CODE IOCTL_STORAGE_EVENT_NOTIFICATION = new CTL_CODE(IOCTL_STORAGE_BASE, 0x724, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public const uint IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = (((IOCTL_VOLUME_BASE) * (2 ^ 16)) | ((FILE_ANY_ACCESS) * (2 ^ 14)) | ((0) * (2 ^ 2)) | (METHOD_BUFFERED));
        public const uint IOCTL_VOLUME_BASE = 86;

        //;
        // IoControlCode values for disk devices.;
        //;

        public static readonly CTL_CODE IOCTL_DISK_GET_DRIVE_GEOMETRY = new CTL_CODE(IOCTL_DISK_BASE, 0x0, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_GET_PARTITION_INFO = new CTL_CODE(IOCTL_DISK_BASE, 0x1, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_SET_PARTITION_INFO = new CTL_CODE(IOCTL_DISK_BASE, 0x2, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_GET_DRIVE_LAYOUT = new CTL_CODE(IOCTL_DISK_BASE, 0x3, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_SET_DRIVE_LAYOUT = new CTL_CODE(IOCTL_DISK_BASE, 0x4, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_VERIFY = new CTL_CODE(IOCTL_DISK_BASE, 0x5, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_FORMAT_TRACKS = new CTL_CODE(IOCTL_DISK_BASE, 0x6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_REASSIGN_BLOCKS = new CTL_CODE(IOCTL_DISK_BASE, 0x7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_PERFORMANCE = new CTL_CODE(IOCTL_DISK_BASE, 0x8, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_IS_WRITABLE = new CTL_CODE(IOCTL_DISK_BASE, 0x9, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_LOGGING = new CTL_CODE(IOCTL_DISK_BASE, 0xA, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_FORMAT_TRACKS_EX = new CTL_CODE(IOCTL_DISK_BASE, 0xB, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_HISTOGRAM_STRUCTURE = new CTL_CODE(IOCTL_DISK_BASE, 0xC, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_HISTOGRAM_DATA = new CTL_CODE(IOCTL_DISK_BASE, 0xD, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_HISTOGRAM_RESET = new CTL_CODE(IOCTL_DISK_BASE, 0xE, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_REQUEST_STRUCTURE = new CTL_CODE(IOCTL_DISK_BASE, 0xF, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_REQUEST_DATA = new CTL_CODE(IOCTL_DISK_BASE, 0x10, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_PERFORMANCE_OFF = new CTL_CODE(IOCTL_DISK_BASE, 0x18, METHOD_BUFFERED, FILE_ANY_ACCESS);

        //if(_WIN32_WINNT >= 0x0400);
        public static readonly CTL_CODE IOCTL_DISK_CONTROLLER_NUMBER = new CTL_CODE(IOCTL_DISK_BASE, 0x11, METHOD_BUFFERED, FILE_ANY_ACCESS);

        //;
        // IOCTL support for SMART drive fault prediction.;
        //;

        public static readonly CTL_CODE SMART_GET_VERSION = new CTL_CODE(IOCTL_DISK_BASE, 0x20, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE SMART_SEND_DRIVE_COMMAND = new CTL_CODE(IOCTL_DISK_BASE, 0x21, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE SMART_RCV_DRIVE_DATA = new CTL_CODE(IOCTL_DISK_BASE, 0x22, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        //endif /* _WIN32_WINNT >= 0x0400 */;

        //if (_WIN32_WINNT >= 0x500);

        //;
        // New IOCTLs for GUID Partition tabled disks.;
        //;

        public static readonly CTL_CODE IOCTL_DISK_GET_PARTITION_INFO_EX = new CTL_CODE(IOCTL_DISK_BASE, 0x12, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_SET_PARTITION_INFO_EX = new CTL_CODE(IOCTL_DISK_BASE, 0x13, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_GET_DRIVE_LAYOUT_EX = new CTL_CODE(IOCTL_DISK_BASE, 0x14, METHOD_BUFFERED, FILE_ANY_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_SET_DRIVE_LAYOUT_EX = new CTL_CODE(IOCTL_DISK_BASE, 0x15, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_CREATE_DISK = new CTL_CODE(IOCTL_DISK_BASE, 0x16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_GET_LENGTH_INFO = new CTL_CODE(IOCTL_DISK_BASE, 0x17, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_GET_DRIVE_GEOMETRY_EX = new CTL_CODE(IOCTL_DISK_BASE, 0x28, METHOD_BUFFERED, FILE_ANY_ACCESS);

        //endif /* _WIN32_WINNT >= 0x0500 */;

        //if (_WIN32_WINNT >= 0x0502);

        //;
        // New IOCTL for disk devices that support 8 byte LBA;
        //;
        public static readonly CTL_CODE IOCTL_DISK_REASSIGN_BLOCKS_EX = new CTL_CODE(IOCTL_DISK_BASE, 0x29, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        //End If //_WIN32_WINNT >= 0x0502;

        //if(_WIN32_WINNT >= 0x0500);
        public static readonly CTL_CODE IOCTL_DISK_UPDATE_DRIVE_SIZE = new CTL_CODE(IOCTL_DISK_BASE, 0x32, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        public static readonly CTL_CODE IOCTL_DISK_GROW_PARTITION = new CTL_CODE(IOCTL_DISK_BASE, 0x34, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        public static readonly CTL_CODE IOCTL_DISK_GET_CACHE_INFORMATION = new CTL_CODE(IOCTL_DISK_BASE, 0x35, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_SET_CACHE_INFORMATION = new CTL_CODE(IOCTL_DISK_BASE, 0x36, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        //If (NTDDI_VERSION < NTDDI_WS03) Then;
        public static readonly CTL_CODE IOCTL_DISK_GET_WRITE_CACHE_STATE = new CTL_CODE(IOCTL_DISK_BASE, 0x37, METHOD_BUFFERED, FILE_READ_ACCESS);

        //Else;
        public static readonly CTL_CODE OBSOLETE_DISK_GET_WRITE_CACHE_STATE = new CTL_CODE(IOCTL_DISK_BASE, 0x37, METHOD_BUFFERED, FILE_READ_ACCESS);

        //End If;
        public static readonly CTL_CODE IOCTL_DISK_DELETE_DRIVE_LAYOUT = new CTL_CODE(IOCTL_DISK_BASE, 0x40, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);

        //;
        // Called to flush cached information that the driver may have about this;
        // device's characteristics.  Not all drivers cache characteristics, and not;
        // cached properties can be flushed.  This simply serves as an update to the;
        // driver that it may want to do an expensive reexamination of the device's;
        // characteristics now (fixed media size, partition table, etc...);
        //;

        public static readonly CTL_CODE IOCTL_DISK_UPDATE_PROPERTIES = new CTL_CODE(IOCTL_DISK_BASE, 0x50, METHOD_BUFFERED, FILE_ANY_ACCESS);

        //;
        //  Special IOCTLs needed to support PC-98 machines in Japan;
        //;

        public static readonly CTL_CODE IOCTL_DISK_FORMAT_DRIVE = new CTL_CODE(IOCTL_DISK_BASE, 0xF3, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_SENSE_DEVICE = new CTL_CODE(IOCTL_DISK_BASE, 0xF8, METHOD_BUFFERED, FILE_ANY_ACCESS);

        //endif /* _WIN32_WINNT >= 0x0500 */;

        //;
        // The following device control codes are common for all class drivers.  The;
        // functions codes defined here must match all of the other class drivers.;
        //;
        // Warning: these codes will be replaced in the future by equivalent;
        // IOCTL_STORAGE codes;
        //;

        public static readonly CTL_CODE IOCTL_DISK_CHECK_VERIFY = new CTL_CODE(IOCTL_DISK_BASE, 0x200, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_MEDIA_REMOVAL = new CTL_CODE(IOCTL_DISK_BASE, 0x201, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_EJECT_MEDIA = new CTL_CODE(IOCTL_DISK_BASE, 0x202, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_LOAD_MEDIA = new CTL_CODE(IOCTL_DISK_BASE, 0x203, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_RESERVE = new CTL_CODE(IOCTL_DISK_BASE, 0x204, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_RELEASE = new CTL_CODE(IOCTL_DISK_BASE, 0x205, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_FIND_NEW_DEVICES = new CTL_CODE(IOCTL_DISK_BASE, 0x206, METHOD_BUFFERED, FILE_READ_ACCESS);
        public static readonly CTL_CODE IOCTL_DISK_GET_MEDIA_TYPES = new CTL_CODE(IOCTL_DISK_BASE, 0x300, METHOD_BUFFERED, FILE_ANY_ACCESS);

        //;

        public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);

        public const uint DELETE = (0x10000);
        public const uint READ_CONTROL = (0x20000);
        public const uint WRITE_DAC = (0x40000);
        public const uint WRITE_OWNER = (0x80000);
        public const uint SYNCHRONIZE = (0x100000);

        public const uint STANDARD_RIGHTS_REQUIRED = (0xF0000);

        public const uint STANDARD_RIGHTS_READ = (READ_CONTROL);
        public const uint STANDARD_RIGHTS_WRITE = (READ_CONTROL);
        public const uint STANDARD_RIGHTS_EXECUTE = (READ_CONTROL);

        public const uint STANDARD_RIGHTS_ALL = (0x1F0000);

        public const uint SPECIFIC_RIGHTS_ALL = (0xFFFF);

        //
        // AccessSystemAcl access type
        //

        public const uint ACCESS_SYSTEM_SECURITY = (0x1000000);

        //
        // MaximumAllowed access type
        //

        public const uint MAXIMUM_ALLOWED = (0x2000000);

        //

        public const uint  FILE_DEVICE_BEEP = 0x1;
        public const uint  FILE_DEVICE_CD_ROM = 0x2;
        public const uint  FILE_DEVICE_CD_ROM_FILE_SYSTEM = 0x3;
        public const uint  FILE_DEVICE_CONTROLLER = 0x4;
        public const uint  FILE_DEVICE_DATALINK = 0x5;
        public const uint  FILE_DEVICE_DFS = 0x6;
        public const uint  FILE_DEVICE_DISK = 0x7;
        public const uint  FILE_DEVICE_DISK_FILE_SYSTEM = 0x8;
        public const uint  FILE_DEVICE_FILE_SYSTEM = 0x9;
        public const uint  FILE_DEVICE_INPORT_PORT = 0xA;
        public const uint  FILE_DEVICE_KEYBOARD = 0xB;
        public const uint  FILE_DEVICE_MAILSLOT = 0xC;
        public const uint  FILE_DEVICE_MIDI_IN = 0xD;
        public const uint  FILE_DEVICE_MIDI_OUT = 0xE;
        public const uint  FILE_DEVICE_MOUSE = 0xF;
        public const uint  FILE_DEVICE_MULTI_UNC_PROVIDER = 0x10;
        public const uint  FILE_DEVICE_NAMED_PIPE = 0x11;
        public const uint  FILE_DEVICE_NETWORK = 0x12;
        public const uint  FILE_DEVICE_NETWORK_BROWSER = 0x13;
        public const uint  FILE_DEVICE_NETWORK_FILE_SYSTEM = 0x14;
        public const uint  FILE_DEVICE_NULL = 0x15;
        public const uint  FILE_DEVICE_PARALLEL_PORT = 0x16;
        public const uint  FILE_DEVICE_PHYSICAL_NETCARD = 0x17;
        public const uint  FILE_DEVICE_PRINTER = 0x18;
        public const uint  FILE_DEVICE_SCANNER = 0x19;
        public const uint  FILE_DEVICE_SERIAL_MOUSE_PORT = 0x1A;
        public const uint  FILE_DEVICE_SERIAL_PORT = 0x1B;
        public const uint  FILE_DEVICE_SCREEN = 0x1C;
        public const uint  FILE_DEVICE_SOUND = 0x1D;
        public const uint  FILE_DEVICE_STREAMS = 0x1E;
        public const uint  FILE_DEVICE_TAPE = 0x1F;
        public const uint  FILE_DEVICE_TAPE_FILE_SYSTEM = 0x20;
        public const uint  FILE_DEVICE_TRANSPORT = 0x21;
        public const uint  FILE_DEVICE_UNKNOWN = 0x22;
        public const uint  FILE_DEVICE_VIDEO = 0x23;
        public const uint  FILE_DEVICE_VIRTUAL_DISK = 0x24;
        public const uint  FILE_DEVICE_WAVE_IN = 0x25;
        public const uint  FILE_DEVICE_WAVE_OUT = 0x26;
        public const uint  FILE_DEVICE_8042_PORT = 0x27;
        public const uint  FILE_DEVICE_NETWORK_REDIRECTOR = 0x28;
        public const uint  FILE_DEVICE_BATTERY = 0x29;
        public const uint  FILE_DEVICE_BUS_EXTENDER = 0x2A;
        public const uint  FILE_DEVICE_MODEM = 0x2B;
        public const uint  FILE_DEVICE_VDM = 0x2C;
        public const uint  FILE_DEVICE_MASS_STORAGE = 0x2D;
        public const uint  FILE_DEVICE_SMB = 0x2E;
        public const uint  FILE_DEVICE_KS = 0x2F;
        public const uint  FILE_DEVICE_CHANGER = 0x30;
        public const uint  FILE_DEVICE_SMARTCARD = 0x31;
        public const uint  FILE_DEVICE_ACPI = 0x32;
        public const uint  FILE_DEVICE_DVD = 0x33;
        public const uint  FILE_DEVICE_FULLSCREEN_VIDEO = 0x34;
        public const uint  FILE_DEVICE_DFS_FILE_SYSTEM = 0x35;
        public const uint  FILE_DEVICE_DFS_VOLUME = 0x36;
        public const uint  FILE_DEVICE_SERENUM = 0x37;
        public const uint  FILE_DEVICE_TERMSRV = 0x38;
        public const uint  FILE_DEVICE_KSEC = 0x39;
        public const uint  FILE_DEVICE_FIPS = 0x3A;
        public const uint  FILE_DEVICE_INFINIBAND = 0x3B;
        public const uint  FILE_DEVICE_VMBUS = 0x3E;
        public const uint  FILE_DEVICE_CRYPT_PROVIDER = 0x3F;
        public const uint  FILE_DEVICE_WPD = 0x40;
        public const uint  FILE_DEVICE_BLUETOOTH = 0x41;
        public const uint  FILE_DEVICE_MT_COMPOSITE = 0x42;
        public const uint  FILE_DEVICE_MT_TRANSPORT = 0x43;
        public const uint  FILE_DEVICE_BIOMETRIC = 0x44;
        public const uint  FILE_DEVICE_PMI = 0x45;
        public const uint  FILE_DEVICE_EHSTOR = 0x46;
        public const uint  FILE_DEVICE_DEVAPI = 0x47;
        public const uint  FILE_DEVICE_GPIO = 0x48;
        public const uint  FILE_DEVICE_USBEX = 0x49;
        public const uint  FILE_DEVICE_CONSOLE = 0x50;
        public const uint  FILE_DEVICE_NFP = 0x51;
        public const uint  FILE_DEVICE_SYSENV = 0x52;
        public const uint  FILE_DEVICE_VIRTUAL_BLOCK = 0x53;
        public const uint  FILE_DEVICE_POINT_OF_SERVICE = 0x54;
        public const uint  FILE_DEVICE_AVIO = 0x99;

        public const uint  FILE_READ_DATA = (0x1);    // file & pipe
        public const uint  FILE_LIST_DIRECTORY = (0x1);    // directory

        public const uint  FILE_WRITE_DATA = (0x2);    // file & pipe
        public const uint  FILE_ADD_FILE = (0x2);    // directory

        public const uint  FILE_APPEND_DATA = (0x4);    // file
        public const uint  FILE_ADD_SUBDIRECTORY = (0x4);    // directory
        public const uint  FILE_CREATE_PIPE_INSTANCE = (0x4);    // named pipe

        public const uint  FILE_READ_EA = (0x8);    // file & directory

        public const uint  FILE_WRITE_EA = (0x10);    // file & directory

        public const uint  FILE_EXECUTE = (0x20);    // file
        public const uint  FILE_TRAVERSE = (0x20);    // directory

        public const uint  FILE_DELETE_CHILD = (0x40);    // directory

        public const uint  FILE_READ_ATTRIBUTES = (0x80);    // all

        public const uint  FILE_WRITE_ATTRIBUTES = (0x100);    // all

        public const uint  FILE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF);

        public const uint  FILE_GENERIC_READ = (STANDARD_RIGHTS_READ |
                                           FILE_READ_DATA |
                                           FILE_READ_ATTRIBUTES |
                                           FILE_READ_EA |
                                           SYNCHRONIZE);

        public const uint  FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE |
                                           FILE_WRITE_DATA |
                                           FILE_WRITE_ATTRIBUTES |
                                           FILE_WRITE_EA |
                                           FILE_APPEND_DATA |
                                           SYNCHRONIZE);

        public const uint  FILE_GENERIC_EXECUTE = (STANDARD_RIGHTS_EXECUTE |
                                           FILE_READ_ATTRIBUTES |
                                           FILE_EXECUTE |
                                           SYNCHRONIZE);

        public const uint  FILE_SHARE_READ = 0x1;
        public const uint  FILE_SHARE_WRITE = 0x2;
        public const uint  FILE_SHARE_DELETE = 0x4;

        public static readonly CTL_CODE FSCTL_REQUEST_OPLOCK_LEVEL_1 = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_REQUEST_OPLOCK_LEVEL_2 = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 1, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_REQUEST_BATCH_OPLOCK = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_OPLOCK_BREAK_ACKNOWLEDGE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 3, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_OPBATCH_ACK_CLOSE_PENDING = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 4, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_OPLOCK_BREAK_NOTIFY = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 5, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_LOCK_VOLUME = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_UNLOCK_VOLUME = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 7, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_DISMOUNT_VOLUME = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // decommissioned fsctl value                                              9
        public static readonly CTL_CODE FSCTL_IS_VOLUME_MOUNTED = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 10, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_IS_PATHNAME_VALID = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 11, METHOD_BUFFERED, FILE_ANY_ACCESS); // PATHNAME_BUFFER,

        public static readonly CTL_CODE FSCTL_MARK_VOLUME_DIRTY = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 12, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // decommissioned fsctl value                                             13
        public static readonly CTL_CODE FSCTL_QUERY_RETRIEVAL_POINTERS = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 14, METHOD_NEITHER, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_GET_COMPRESSION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 15, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_SET_COMPRESSION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 16, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA);

        // decommissioned fsctl value                                             17
        // decommissioned fsctl value                                             18
        public static readonly CTL_CODE FSCTL_SET_BOOTLOADER_ACCESSED = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 19, METHOD_NEITHER, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_MARK_AS_SYSTEM_HIVE = FSCTL_SET_BOOTLOADER_ACCESSED;
        public static readonly CTL_CODE FSCTL_OPLOCK_BREAK_ACK_NO_2 = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 20, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_INVALIDATE_VOLUMES = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 21, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_QUERY_FAT_BPB = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 22, METHOD_BUFFERED, FILE_ANY_ACCESS); // FSCTL_QUERY_FAT_BPB_BUFFER

        public static readonly CTL_CODE FSCTL_REQUEST_FILTER_OPLOCK = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 23, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_FILESYSTEM_GET_STATISTICS = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 24, METHOD_BUFFERED, FILE_ANY_ACCESS); // FILESYSTEM_STATISTICS

        // if  (_WIN32_WINNT >= _WIN32_WINNT_NT4);
        public static readonly CTL_CODE FSCTL_GET_NTFS_VOLUME_DATA = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 25, METHOD_BUFFERED, FILE_ANY_ACCESS); // NTFS_VOLUME_DATA_BUFFER

        public static readonly CTL_CODE FSCTL_GET_NTFS_FILE_RECORD = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 26, METHOD_BUFFERED, FILE_ANY_ACCESS); // NTFS_FILE_RECORD_INPUT_BUFFER, NTFS_FILE_RECORD_OUTPUT_BUFFER

        public static readonly CTL_CODE FSCTL_GET_VOLUME_BITMAP = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 27, METHOD_NEITHER, FILE_ANY_ACCESS); // STARTING_LCN_INPUT_BUFFER, VOLUME_BITMAP_BUFFER

        public static readonly CTL_CODE FSCTL_GET_RETRIEVAL_POINTERS = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 28, METHOD_NEITHER, FILE_ANY_ACCESS); // STARTING_VCN_INPUT_BUFFER, RETRIEVAL_POINTERS_BUFFER

        public static readonly CTL_CODE FSCTL_MOVE_FILE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 29, METHOD_BUFFERED, FILE_SPECIAL_ACCESS); // MOVE_FILE_DATA,

        public static readonly CTL_CODE FSCTL_IS_VOLUME_DIRTY = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 30, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // decommissioned fsctl value                                             31
        public static readonly CTL_CODE FSCTL_ALLOW_EXTENDED_DASD_IO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 32, METHOD_NEITHER, FILE_ANY_ACCESS);

        // endif  /* _WIN32_WINNT >= _WIN32_WINNT_NT4 */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_WIN2K);
        // decommissioned fsctl value                                             33
        // decommissioned fsctl value                                             34
        public static readonly CTL_CODE FSCTL_FIND_FILES_BY_SID = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 35, METHOD_NEITHER, FILE_ANY_ACCESS);

        // decommissioned fsctl value                                             36
        // decommissioned fsctl value                                             37
        public static readonly CTL_CODE FSCTL_SET_OBJECT_ID = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 38, METHOD_BUFFERED, FILE_SPECIAL_ACCESS); // FILE_OBJECTID_BUFFER

        public static readonly CTL_CODE FSCTL_GET_OBJECT_ID = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 39, METHOD_BUFFERED, FILE_ANY_ACCESS); // FILE_OBJECTID_BUFFER

        public static readonly CTL_CODE FSCTL_DELETE_OBJECT_ID = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 40, METHOD_BUFFERED, FILE_SPECIAL_ACCESS);

        public static readonly CTL_CODE FSCTL_SET_REPARSE_POINT = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS); // REPARSE_DATA_BUFFER,

        public static readonly CTL_CODE FSCTL_GET_REPARSE_POINT = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS); // REPARSE_DATA_BUFFER

        public static readonly CTL_CODE FSCTL_DELETE_REPARSE_POINT = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_SPECIAL_ACCESS); // REPARSE_DATA_BUFFER,

        public static readonly CTL_CODE FSCTL_ENUM_USN_DATA = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 44, METHOD_NEITHER, FILE_ANY_ACCESS); // MFT_ENUM_DATA,

        public static readonly CTL_CODE FSCTL_SECURITY_ID_CHECK = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 45, METHOD_NEITHER, FILE_READ_DATA); // BULK_SECURITY_TEST_DATA,

        public static readonly CTL_CODE FSCTL_READ_USN_JOURNAL = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 46, METHOD_NEITHER, FILE_ANY_ACCESS); // READ_USN_JOURNAL_DATA, USN

        public static readonly CTL_CODE FSCTL_SET_OBJECT_ID_EXTENDED = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 47, METHOD_BUFFERED, FILE_SPECIAL_ACCESS);

        public static readonly CTL_CODE FSCTL_CREATE_OR_GET_OBJECT_ID = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 48, METHOD_BUFFERED, FILE_ANY_ACCESS); // FILE_OBJECTID_BUFFER

        public static readonly CTL_CODE FSCTL_SET_SPARSE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_SPECIAL_ACCESS);

        public static readonly CTL_CODE FSCTL_SET_ZERO_DATA = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 50, METHOD_BUFFERED, FILE_WRITE_DATA); // FILE_ZERO_DATA_INFORMATION,

        public static readonly CTL_CODE FSCTL_QUERY_ALLOCATED_RANGES = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 51, METHOD_NEITHER, FILE_READ_DATA); // FILE_ALLOCATED_RANGE_BUFFER, FILE_ALLOCATED_RANGE_BUFFER

        public static readonly CTL_CODE FSCTL_ENABLE_UPGRADE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 52, METHOD_BUFFERED, FILE_WRITE_DATA);

        public static readonly CTL_CODE FSCTL_SET_ENCRYPTION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 53, METHOD_NEITHER, FILE_ANY_ACCESS); // ENCRYPTION_BUFFER, DECRYPTION_STATUS_BUFFER

        public static readonly CTL_CODE FSCTL_ENCRYPTION_FSCTL_IO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 54, METHOD_NEITHER, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_WRITE_RAW_ENCRYPTED = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 55, METHOD_NEITHER, FILE_SPECIAL_ACCESS); // ENCRYPTED_DATA_INFO, EXTENDED_ENCRYPTED_DATA_INFO

        public static readonly CTL_CODE FSCTL_READ_RAW_ENCRYPTED = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 56, METHOD_NEITHER, FILE_SPECIAL_ACCESS); // REQUEST_RAW_ENCRYPTED_DATA, ENCRYPTED_DATA_INFO, EXTENDED_ENCRYPTED_DATA_INFO

        public static readonly CTL_CODE FSCTL_CREATE_USN_JOURNAL = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 57, METHOD_NEITHER, FILE_ANY_ACCESS); // CREATE_USN_JOURNAL_DATA,

        public static readonly CTL_CODE FSCTL_READ_FILE_USN_DATA = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 58, METHOD_NEITHER, FILE_ANY_ACCESS); // Read the Usn Record for a file

        public static readonly CTL_CODE FSCTL_WRITE_USN_CLOSE_RECORD = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 59, METHOD_NEITHER, FILE_ANY_ACCESS); // Generate Close Usn Record

        public static readonly CTL_CODE FSCTL_EXTEND_VOLUME = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 60, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_QUERY_USN_JOURNAL = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 61, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_DELETE_USN_JOURNAL = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 62, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_MARK_HANDLE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 63, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_SIS_COPYFILE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 64, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_SIS_LINK_FILES = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 65, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA);

        // decommissional fsctl value                                             66
        // decommissioned fsctl value                                             67
        // decommissioned fsctl value                                             68
        public static readonly CTL_CODE FSCTL_RECALL_FILE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 69, METHOD_NEITHER, FILE_ANY_ACCESS);

        // decommissioned fsctl value                                             70
        public static readonly CTL_CODE FSCTL_READ_FROM_PLEX = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 71, METHOD_OUT_DIRECT, FILE_READ_DATA);

        public static readonly CTL_CODE FSCTL_FILE_PREFETCH = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 72, METHOD_BUFFERED, FILE_SPECIAL_ACCESS); // FILE_PREFETCH

        // endif  /* _WIN32_WINNT >= _WIN32_WINNT_WIN2K */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_VISTA);
        public static readonly CTL_CODE FSCTL_MAKE_MEDIA_COMPATIBLE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 76, METHOD_BUFFERED, FILE_WRITE_DATA); // UDFS R/W

        public static readonly CTL_CODE FSCTL_SET_DEFECT_MANAGEMENT = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 77, METHOD_BUFFERED, FILE_WRITE_DATA); // UDFS R/W

        public static readonly CTL_CODE FSCTL_QUERY_SPARING_INFO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 78, METHOD_BUFFERED, FILE_ANY_ACCESS); // UDFS R/W

        public static readonly CTL_CODE FSCTL_QUERY_ON_DISK_VOLUME_INFO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 79, METHOD_BUFFERED, FILE_ANY_ACCESS); // C/UDFS

        public static readonly CTL_CODE FSCTL_SET_VOLUME_COMPRESSION_STATE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 80, METHOD_BUFFERED, FILE_SPECIAL_ACCESS); // VOLUME_COMPRESSION_STATE

        // decommissioned fsctl value                                                 80
        public static readonly CTL_CODE FSCTL_TXFS_MODIFY_RM = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 81, METHOD_BUFFERED, FILE_WRITE_DATA); // TxF

        public static readonly CTL_CODE FSCTL_TXFS_QUERY_RM_INFORMATION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 82, METHOD_BUFFERED, FILE_READ_DATA); // TxF

        // decommissioned fsctl value                                                 83
        public static readonly CTL_CODE FSCTL_TXFS_ROLLFORWARD_REDO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 84, METHOD_BUFFERED, FILE_WRITE_DATA); // TxF

        public static readonly CTL_CODE FSCTL_TXFS_ROLLFORWARD_UNDO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 85, METHOD_BUFFERED, FILE_WRITE_DATA); // TxF

        public static readonly CTL_CODE FSCTL_TXFS_START_RM = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 86, METHOD_BUFFERED, FILE_WRITE_DATA); // TxF

        public static readonly CTL_CODE FSCTL_TXFS_SHUTDOWN_RM = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 87, METHOD_BUFFERED, FILE_WRITE_DATA); // TxF

        public static readonly CTL_CODE FSCTL_TXFS_READ_BACKUP_INFORMATION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 88, METHOD_BUFFERED, FILE_READ_DATA); // TxF

        public static readonly CTL_CODE FSCTL_TXFS_WRITE_BACKUP_INFORMATION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 89, METHOD_BUFFERED, FILE_WRITE_DATA); // TxF

        public static readonly CTL_CODE FSCTL_TXFS_CREATE_SECONDARY_RM = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 90, METHOD_BUFFERED, FILE_WRITE_DATA); // TxF

        public static readonly CTL_CODE FSCTL_TXFS_GET_METADATA_INFO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 91, METHOD_BUFFERED, FILE_READ_DATA); // TxF

        public static readonly CTL_CODE FSCTL_TXFS_GET_TRANSACTED_VERSION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 92, METHOD_BUFFERED, FILE_READ_DATA); // TxF

        // decommissioned fsctl value                                                 93
        public static readonly CTL_CODE FSCTL_TXFS_SAVEPOINT_INFORMATION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 94, METHOD_BUFFERED, FILE_WRITE_DATA); // TxF

        public static readonly CTL_CODE FSCTL_TXFS_CREATE_MINIVERSION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 95, METHOD_BUFFERED, FILE_WRITE_DATA); // TxF

        // decommissioned fsctl value                                                 96
        // decommissioned fsctl value                                                 97
        // decommissioned fsctl value                                                 98
        public static readonly CTL_CODE FSCTL_TXFS_TRANSACTION_ACTIVE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 99, METHOD_BUFFERED, FILE_READ_DATA); // TxF

        public static readonly CTL_CODE FSCTL_SET_ZERO_ON_DEALLOCATION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 101, METHOD_BUFFERED, FILE_SPECIAL_ACCESS);

        public static readonly CTL_CODE FSCTL_SET_REPAIR = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 102, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_GET_REPAIR = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 103, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_WAIT_FOR_REPAIR = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 104, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // decommissioned fsctl value                                                 105
        public static readonly CTL_CODE FSCTL_INITIATE_REPAIR = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 106, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_CSC_INTERNAL = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 107, METHOD_NEITHER, FILE_ANY_ACCESS); // CSC internal implementation

        public static readonly CTL_CODE FSCTL_SHRINK_VOLUME = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 108, METHOD_BUFFERED, FILE_SPECIAL_ACCESS); // SHRINK_VOLUME_INFORMATION

        public static readonly CTL_CODE FSCTL_SET_SHORT_NAME_BEHAVIOR = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 109, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_DFSR_SET_GHOST_HANDLE_STATE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 110, METHOD_BUFFERED, FILE_ANY_ACCESS);

        //
        //  Values 111 - 119 are reserved for FSRM.
        //

        public static readonly CTL_CODE FSCTL_TXFS_LIST_TRANSACTION_LOCKED_FILES = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 120, METHOD_BUFFERED, FILE_READ_DATA); // TxF
        public static readonly CTL_CODE FSCTL_TXFS_LIST_TRANSACTIONS = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 121, METHOD_BUFFERED, FILE_READ_DATA); // TxF

        public static readonly CTL_CODE FSCTL_QUERY_PAGEFILE_ENCRYPTION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 122, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // endif  /* _WIN32_WINNT >= _WIN32_WINNT_VISTA */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_VISTA);
        public static readonly CTL_CODE FSCTL_RESET_VOLUME_ALLOCATION_HINTS = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 123, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // endif  /* _WIN32_WINNT >= _WIN32_WINNT_VISTA */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_WIN7);
        public static readonly CTL_CODE FSCTL_QUERY_DEPENDENT_VOLUME = new CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 124, METHOD_BUFFERED, FILE_ANY_ACCESS);   // Dependency File System Filter

        public static readonly CTL_CODE FSCTL_SD_GLOBAL_CHANGE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 125, METHOD_BUFFERED, FILE_ANY_ACCESS); // Query/Change NTFS Security Descriptors

        // endif  /* _WIN32_WINNT >= _WIN32_WINNT_WIN7 */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_VISTA);
        public static readonly CTL_CODE FSCTL_TXFS_READ_BACKUP_INFORMATION2 = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 126, METHOD_BUFFERED, FILE_ANY_ACCESS); // TxF

        // endif  /* _WIN32_WINNT >= _WIN32_WINNT_VISTA */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_WIN7);
        public static readonly CTL_CODE FSCTL_LOOKUP_STREAM_FROM_CLUSTER = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 127, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_TXFS_WRITE_BACKUP_INFORMATION2 = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 128, METHOD_BUFFERED, FILE_ANY_ACCESS); // TxF

        public static readonly CTL_CODE FSCTL_FILE_TYPE_NOTIFICATION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 129, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // endif

        // if  (_WIN32_WINNT >= _WIN32_WINNT_WIN8);
        public static readonly CTL_CODE FSCTL_FILE_LEVEL_TRIM = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 130, METHOD_BUFFERED, FILE_WRITE_DATA);

        // endif  /*_WIN32_WINNT >= _WIN32_WINNT_WIN8 */

        //
        //  Values 131 - 139 are reserved for FSRM.
        //

        //public static readonly CTL_CODE FSCTL_LOCK_VOLUME = new CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS);
        //public static readonly CTL_CODE FSCTL_UNLOCK_VOLUME = new CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  7, METHOD_BUFFERED, FILE_ANY_ACCESS);
        //public static readonly CTL_CODE FSCTL_DISMOUNT_VOLUME = new CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  8, METHOD_BUFFERED, FILE_ANY_ACCESS);


        // if  (_WIN32_WINNT >= _WIN32_WINNT_WIN7);
        public static readonly CTL_CODE FSCTL_GET_BOOT_AREA_INFO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 140, METHOD_BUFFERED, FILE_ANY_ACCESS); // BOOT_AREA_INFO

        public static readonly CTL_CODE FSCTL_GET_RETRIEVAL_POINTER_BASE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 141, METHOD_BUFFERED, FILE_ANY_ACCESS); // RETRIEVAL_POINTER_BASE

        public static readonly CTL_CODE FSCTL_SET_PERSISTENT_VOLUME_STATE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 142, METHOD_BUFFERED, FILE_ANY_ACCESS); // FILE_FS_PERSISTENT_VOLUME_INFORMATION

        public static readonly CTL_CODE FSCTL_QUERY_PERSISTENT_VOLUME_STATE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 143, METHOD_BUFFERED, FILE_ANY_ACCESS); // FILE_FS_PERSISTENT_VOLUME_INFORMATION

        public static readonly CTL_CODE FSCTL_REQUEST_OPLOCK = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 144, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_CSV_TUNNEL_REQUEST = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 145, METHOD_BUFFERED, FILE_ANY_ACCESS); // CSV_TUNNEL_REQUEST

        public static readonly CTL_CODE FSCTL_IS_CSV_FILE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 146, METHOD_BUFFERED, FILE_ANY_ACCESS); // IS_CSV_FILE

        public static readonly CTL_CODE FSCTL_QUERY_FILE_SYSTEM_RECOGNITION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 147, METHOD_BUFFERED, FILE_ANY_ACCESS); //

        public static readonly CTL_CODE FSCTL_CSV_GET_VOLUME_PATH_NAME = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 148, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_CSV_GET_VOLUME_NAME_FOR_VOLUME_MOUNT_POINT = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 149, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_CSV_GET_VOLUME_PATH_NAMES_FOR_VOLUME_NAME = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 150, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_IS_FILE_ON_CSV_VOLUME = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 151, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // endif  /* _WIN32_WINNT >= _WIN32_WINNT_WIN7 */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_WIN8);
        public static readonly CTL_CODE FSCTL_CORRUPTION_HANDLING = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 152, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_OFFLOAD_READ = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 153, METHOD_BUFFERED, FILE_READ_ACCESS);

        public static readonly CTL_CODE FSCTL_OFFLOAD_WRITE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 154, METHOD_BUFFERED, FILE_WRITE_ACCESS);

        // endif  /*_WIN32_WINNT >= _WIN32_WINNT_WIN8 */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_WIN7);
        public static readonly CTL_CODE FSCTL_CSV_INTERNAL = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 155, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // endif  /* _WIN32_WINNT >= _WIN32_WINNT_WIN7 */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_WIN8);
        public static readonly CTL_CODE FSCTL_SET_PURGE_FAILURE_MODE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 156, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_QUERY_FILE_LAYOUT = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 157, METHOD_NEITHER, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_IS_VOLUME_OWNED_BYCSVFS = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 158, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_GET_INTEGRITY_INFORMATION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 159, METHOD_BUFFERED, FILE_ANY_ACCESS);                  // FSCTL_GET_INTEGRITY_INFORMATION_BUFFER

        public static readonly CTL_CODE FSCTL_SET_INTEGRITY_INFORMATION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 160, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA); // FSCTL_SET_INTEGRITY_INFORMATION_BUFFER

        public static readonly CTL_CODE FSCTL_QUERY_FILE_REGIONS = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 161, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // endif  /*_WIN32_WINNT >= _WIN32_WINNT_WIN8 */

        //
        // Dedup FSCTLs
        // Values 162 - 170 are reserved for Dedup.
        //

        // if  (_WIN32_WINNT >= _WIN32_WINNT_WIN8);
        public static readonly CTL_CODE FSCTL_DEDUP_FILE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 165, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_DEDUP_QUERY_FILE_HASHES = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 166, METHOD_NEITHER, FILE_READ_DATA);

        public static readonly CTL_CODE FSCTL_DEDUP_QUERY_RANGE_STATE = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 167, METHOD_NEITHER, FILE_READ_DATA);

        public static readonly CTL_CODE FSCTL_DEDUP_QUERY_REPARSE_INFO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 168, METHOD_NEITHER, FILE_ANY_ACCESS);

        // endif  /*_WIN32_WINNT >= _WIN32_WINNT_WIN8 */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_WIN8);
        public static readonly CTL_CODE FSCTL_RKF_INTERNAL = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 171, METHOD_NEITHER, FILE_ANY_ACCESS); // Resume Key Filter

        public static readonly CTL_CODE FSCTL_SCRUB_DATA = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 172, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_REPAIR_COPIES = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 173, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA);

        public static readonly CTL_CODE FSCTL_DISABLE_LOCAL_BUFFERING = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 174, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_CSV_MGMT_LOCK = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 175, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_CSV_QUERY_DOWN_LEVEL_FILE_SYSTEM_CHARACTERISTICS = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 176, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_ADVANCE_FILE_ID = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 177, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_CSV_SYNC_TUNNEL_REQUEST = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 178, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_CSV_QUERY_VETO_FILE_DIRECT_IO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 179, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_WRITE_USN_REASON = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 180, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_CSV_CONTROL = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 181, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_GET_REFS_VOLUME_DATA = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 182, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_CSV_H_BREAKING_SYNC_TUNNEL_REQUEST = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 185, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // endif  /*_WIN32_WINNT >= _WIN32_WINNT_WIN8 */

        // if  (_WIN32_WINNT >= _WIN32_WINNT_WINBLUE);
        public static readonly CTL_CODE FSCTL_QUERY_STORAGE_CLASSES = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 187, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_QUERY_REGION_INFO = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 188, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_USN_TRACK_MODIFIED_RANGES = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 189, METHOD_BUFFERED, FILE_ANY_ACCESS); // USN_TRACK_MODIFIED_RANGES

        // endif  /* (_WIN32_WINNT >= _WIN32_WINNT_WINBLUE) */
        // if  (_WIN32_WINNT >= _WIN32_WINNT_WINBLUE);
        public static readonly CTL_CODE FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 192, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_SVHDX_SYNC_TUNNEL_REQUEST = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 193, METHOD_BUFFERED, FILE_ANY_ACCESS);

        public static readonly CTL_CODE FSCTL_SVHDX_SET_INITIATOR_INFORMATION = new  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 194, METHOD_BUFFERED, FILE_ANY_ACCESS);

        // endif  /* (_WIN32_WINNT >= _WIN32_WINNT_WINBLUE) */
        //
        // AVIO IOCTLS.
        //

        public static readonly CTL_CODE IOCTL_AVIO_ALLOCATE_STREAM = new  CTL_CODE(FILE_DEVICE_AVIO, 1, METHOD_BUFFERED, FILE_SPECIAL_ACCESS);

        public static readonly CTL_CODE IOCTL_AVIO_FREE_STREAM = new  CTL_CODE(FILE_DEVICE_AVIO, 2, METHOD_BUFFERED, FILE_SPECIAL_ACCESS);

        public static readonly CTL_CODE IOCTL_AVIO_MODIFY_STREAM = new  CTL_CODE(FILE_DEVICE_AVIO, 3, METHOD_BUFFERED, FILE_SPECIAL_ACCESS);
    }

    #endregion Interop

    /// <summary>
    /// DiskUtil physical drive enumerator.
    /// </summary>
    public static class DiskUtil
    {
        public static DiskInfo[] EnumDisks()
        {
            List<DiskInfo> disks = new List<DiskInfo>();

            MemPtr mm = new MemPtr();
            IntPtr disk;

            uint c = 0;
            uint cbSize;

            // initialize a bunch of structures ...

            SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA();
            SP_DEVICE_INTERFACE_DATA devInterface = new SP_DEVICE_INTERFACE_DATA();
            SP_DEVICE_INTERFACE_DETAIL_DATA devDetail = new SP_DEVICE_INTERFACE_DETAIL_DATA();
            STORAGE_DEVICE_NUMBER diskNumber;

            DiskInfo devOut;

            // We want disks (but you can do this with literally any kind of device)
            Guid ClassId = SetupApi.GUID_DEVINTERFACE_DISK;

            // Get the devices in the class (interface)!
            IntPtr hDev = SetupApi.SetupDiGetClassDevs(ClassId, IntPtr.Zero, IntPtr.Zero, ClassDevFlags.DeviceInterface | ClassDevFlags.Present);

            if (hDev == IoCtl.INVALID_HANDLE_VALUE) {
                return null;
            }

            // preset the cbSize of the structures so the OS knows what it's playing with...
            devInfo.cbSize = (uint) Marshal.SizeOf(devInfo);
            devInterface.cbSize = (uint) Marshal.SizeOf(devInterface);

            // and ... enumerate!
            while (SetupApi.SetupDiEnumDeviceInterfaces(hDev, IntPtr.Zero, ref ClassId, (uint) c, ref devInterface) != 0)
            {
                devOut = new DiskInfo();

                // get the property bag...

                SetupApi.SetupDiEnumDeviceInfo(hDev, c, ref devInfo);

                // we want these luxurious properties ...

                devOut.HardwareIds = (string[]) SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_HardwareIds, SetupApi.DevPropTypes.StringList);
                devOut.FriendlyName = (string)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_FriendlyName, SetupApi.DevPropTypes.String);
                devOut.PDOName = (string)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_PDOName, SetupApi.DevPropTypes.String);
                devOut.InstallDate = (DateTime)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_FirstInstallDate, SetupApi.DevPropTypes.Date);
                devOut.DeviceInterfaceClassGuid = ClassId;
                devOut.DeviceClassGuid = (Guid)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_ClassGuid, SetupApi.DevPropTypes.Guid);
                devOut.Manufacturer = (string)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_Manufacturer, SetupApi.DevPropTypes.String);
                devOut.Description = (string)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_DeviceDesc, SetupApi.DevPropTypes.String);
                devOut.InstanceId = (string)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_InstanceId, SetupApi.DevPropTypes.String);
                devOut.LocationInfo = (string)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_LocationInfo, SetupApi.DevPropTypes.String);
                devOut.LocationPaths = (string[])SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_LocationPaths, SetupApi.DevPropTypes.String);
                devOut.Parent = (string)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_Parent, SetupApi.DevPropTypes.String);
                devOut.RemovalPolicy = (DeviceRemovalPolicy)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_RemovalPolicy, SetupApi.DevPropTypes.Int32);
                devOut.SafeRemovalRequired = (bool)SetupApi.GetDevProperty(hDev, devInfo, SetupApi.DEVPKEY_Device_SafeRemovalRequired, SetupApi.DevPropTypes.Boolean);

                cbSize = 0;

                // allocate our memory...
                mm.Alloc(Marshal.SizeOf(devDetail));

                // shortcut: not passing the whole structure ... just marking the size where it should be (position 0)...
                mm.intAt(0, Marshal.SizeOf(devDetail));

                // request the size by setting every input to null:
                SetupApi.SetupDiGetDeviceInterfaceDetail(hDev, ref devInterface, IntPtr.Zero, 0, ref cbSize, IntPtr.Zero);

                if (cbSize > 0)
                {
                    mm.ReAlloc(cbSize);

                    // now call for real ...
                    SetupApi.SetupDiGetDeviceInterfaceDetail(hDev,
                        ref devInterface,
                        mm,
                        cbSize,
                        ref cbSize,
                        IntPtr.Zero);

                    // we know this is here ...
                    devOut.DevicePath = mm.GrabString(4);
                    
                    // that was the magic thing we needed!
                    disk = FileIO.CreateFile(devOut.DevicePath, FileAccess.Read, ShareModes.Read | ShareModes.Write, IntPtr.Zero, CreateDisposition.OpenExisting, 0, IntPtr.Zero);

                    if (disk != MemPtr.InvalidHandle)
                    {
                        // we have an open disk:

                        mm.Free();
                        mm.Alloc(Marshal.SizeOf(new STORAGE_DEVICE_NUMBER()));

                        // get the storage device number (aka \\.\PhysicalDriveX)
                        // You can use either DevicePath or PhysicalDriveX to open a disk...
                        // but it takes one to get the other (without WMI)... and it's good to have both on hand...
                        IoCtl.DeviceIoControl(disk,
                                IoCtl.IOCTL_STORAGE_GET_DEVICE_NUMBER,
                                IntPtr.Zero,
                                0,
                                mm,
                                (uint)mm.GetLength(),
                                ref cbSize,
                                IntPtr.Zero);

                        if (cbSize != 0)
                        {
                            diskNumber = mm.ToStruct<STORAGE_DEVICE_NUMBER>();
                            devOut.PhysicalDevice = diskNumber.DeviceNumber;
                        }

                        mm.ReAlloc(Marshal.SizeOf(new DISK_GEOMETRY_EX()));

                        // Now, we get that disk geometry like you wanted...
                        IoCtl.DeviceIoControl(disk,
                                 IoCtl.IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
                                 IntPtr.Zero,
                                 0,
                                 mm,
                                 (uint)mm.GetLength(),
                                 ref cbSize,
                                 IntPtr.Zero);

                        if (cbSize != 0) {
                            devOut.DiskGeometry = mm.ToStruct<DISK_GEOMETRY_EX>();
                        }

                        // we're done!
                        FileIO.CloseHandle(disk);
                        disk = IntPtr.Zero;
                    }
                }

                // Free the mighty unmanaged resources ...
                mm.Free();

                // Add the new disk...
                disks.Add(devOut);
                devOut = null;

                // keep going.
                c++;
            }

            // Close the enumeration...
            SetupApi.SetupDiDestroyDeviceInfoList(hDev);

            // return the new disk array of all the disk device goodness ...
            return disks.ToArray();
        }

        [DllImport("kernel32.dll")]
        internal static extern uint GetLastError();
    }

    public enum DeviceRemovalPolicy : uint
    {
        /// <summary>
        /// The device is not expected to be removed.
        /// </summary>
        /// <remarks></remarks>
        ExpectNoRemoval = 1,

        /// <summary>
        /// The device can be expected to be removed in an orderly fashion.
        /// </summary>
        /// <remarks></remarks>
        ExpectOrderlyRemoval = 2,

        /// <summary>
        /// The device can be expected to be removed without any preparation for removal.
        /// </summary>
        /// <remarks></remarks>
        ExpectSurpriseRemoval = 3
    }

    /// <summary>
    /// Disk Information
    /// </summary>
    public class DiskInfo
    {
        /// <summary>
        /// The physical device path.  This can be used as an alternate path for CreateFile() to open the physical disk.
        /// </summary>
        public string DevicePath { get; internal set; }

        /// <summary>
        /// The "friendly" device name.
        /// </summary>
        public string FriendlyName { get; internal set; }

        /// <summary>
        /// This is the InstanceId.  This can be used to raise the device properties dialog.
        /// </summary>
        public string InstanceId { get; internal set; }

        /// <summary>
        /// Physical location paths.
        /// </summary>
        public string[] LocationPaths { get; internal set; }

        /// <summary>
        /// Physical Hardware Ids.
        /// </summary>
        public string[] HardwareIds { get; internal set; }

        /// <summary>
        /// Specific location information.
        /// </summary>
        public string LocationInfo { get; internal set; }

        /// <summary>
        /// The UINumber
        /// </summary>
        public int UINumber { get; internal set; }

        /// <summary>
        /// The device description.
        /// </summary>
        public string Description { get; internal set; }

        /// <summary>
        /// The device's installation date.
        /// </summary>
        public DateTime InstallDate { get; internal set; }

        /// <summary>
        /// The PDO Name.
        /// </summary>
        public string PDOName { get; internal set; }

        /// <summary>
        /// The manufacturer.
        /// </summary>
        public string Manufacturer { get; internal set; }

        public Guid DeviceInterfaceClassGuid { get; internal set; }

        public Guid DeviceClassGuid { get; internal set; }

        /// <summary>
        /// The InstanceId of the parent device.
        /// </summary>
        public string Parent { get; internal set; }

        /// <summary>
        /// The removal policy of the device.
        /// </summary>
        public DeviceRemovalPolicy RemovalPolicy { get; internal set; }

        /// <summary>
        /// Safe removal requirement.
        /// </summary>
        public bool SafeRemovalRequired { get; internal set; }

        /// <summary>
        /// The physical drive number.
        /// </summary>
        public uint PhysicalDevice { get; internal set; }

        /// <summary>
        /// Detailed disk geometry information.
        /// </summary>
        public DISK_GEOMETRY_EX DiskGeometry { get; internal set; }

        public override string ToString()
        {
            return FriendlyName + " [" + DiskGeometry.ToString() + "]";
        }

        [DllImport("devmgr.dll", CharSet=CharSet.Unicode,EntryPoint="DeviceProperties_RunDLLW")]
        internal static extern bool DeviceProperties_RunDLL(IntPtr hwnd, IntPtr hAppInstance, string cmdLine, int nCmdShow);

        /// <summary>
        /// Opens the hardware properties dialog box for the specified instance id.
        /// </summary>
        /// <remarks></remarks>
        public void OpenDevicePropertiesDialog()
        {
            OpenDeviceProperties(InstanceId);
        }

        /// <summary>
        /// Opens the hardware properties dialog box for the specified instance id.
        /// </summary>
        /// <param name="hwnd">The owner window handle.</param>
        /// <remarks></remarks>
        public void OpenDevicePropertiesDialog(IntPtr hwnd)
        {
            OpenDeviceProperties(InstanceId, hwnd);
        }

        /// <summary>
        /// Opens the hardware properties dialog box for the specified instance id.
        /// </summary>
        /// <param name="InstanceId">The device InstanceId to use to raise the dialog box.</param>
        /// <param name="hwnd">The owner window handle.</param>
        /// <remarks></remarks>
        public static void OpenDeviceProperties(string InstanceId, IntPtr hwnd) {
            DeviceProperties_RunDLL(hwnd, System.Diagnostics.Process.GetCurrentProcess().Handle, "/DeviceId \"" + InstanceId + "\"", 1);
        }

        /// <summary>
        /// Opens the hardware properties dialog box for the specified instance id.
        /// </summary>
        /// <param name="InstanceId">The device InstanceId to use to raise the dialog box.</param>
        /// <remarks></remarks>
        public static void OpenDeviceProperties(string InstanceId)
        {
            DeviceProperties_RunDLL(IntPtr.Zero, System.Diagnostics.Process.GetCurrentProcess().Handle, "/DeviceId \"" + InstanceId + "\"", 1);
        }
    }
}